summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schauer Marin Rodrigues <josch@mister-muffin.de>2023-12-21 12:13:24 +0100
committerJohannes Schauer Marin Rodrigues <josch@mister-muffin.de>2023-12-21 12:13:24 +0100
commit64730b902d0c90cd84852c78795cc4dafb239db8 (patch)
tree531e3260a41dd555eaa52021eb314f81447c800c
parentd66ecf0cbcc1d5734bb882746a2c45a712b4b9b3 (diff)
New upstream version 0.2.6+dfsg
-rw-r--r--.clang-format14
-rw-r--r--CMakeLists.txt257
-rw-r--r--README.md26
-rw-r--r--README_CN.md8
-rw-r--r--README_UK.md2
-rw-r--r--docs/CHANGELOG.md28
-rw-r--r--docs/COMPILE.md57
-rw-r--r--docs/USAGE.md51
-rw-r--r--docs/box64.pod21
-rwxr-xr-xrebuild_wrappers.py1
-rw-r--r--runTest.cmake5
-rw-r--r--src/box64context.c4
-rw-r--r--src/box64version.h2
-rw-r--r--src/custommem.c599
-rw-r--r--src/dynarec/arm64/arm64_emitter.h369
-rw-r--r--src/dynarec/arm64/arm64_lock.S21
-rw-r--r--src/dynarec/arm64/arm64_lock.h12
-rw-r--r--src/dynarec/arm64/arm64_printer.c228
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c765
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c687
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c91
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c412
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c613
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66f0.c303
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66f20f.c93
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66f30f.c64
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c45
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6764_32.c103
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67_32.c72
-rw-r--r--src/dynarec/arm64/dynarec_arm64_d8.c6
-rw-r--r--src/dynarec/arm64/dynarec_arm64_d9.c122
-rw-r--r--src/dynarec/arm64/dynarec_arm64_da.c239
-rw-r--r--src/dynarec/arm64/dynarec_arm64_db.c16
-rw-r--r--src/dynarec/arm64/dynarec_arm64_dc.c6
-rw-r--r--src/dynarec/arm64/dynarec_arm64_dd.c63
-rw-r--r--src/dynarec/arm64/dynarec_arm64_de.c22
-rw-r--r--src/dynarec/arm64/dynarec_arm64_df.c31
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_logic.c60
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_math.c130
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c1011
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_tests.c50
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c1029
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f20f.c70
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c32
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.h5
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c159
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h184
-rw-r--r--src/dynarec/arm64/dynarec_arm64_pass0.h5
-rw-r--r--src/dynarec/arm64/dynarec_arm64_private.h7
-rw-r--r--src/dynarec/dynablock.c19
-rw-r--r--src/dynarec/dynarec.c40
-rw-r--r--src/dynarec/dynarec_native.c91
-rw-r--r--src/dynarec/dynarec_native_functions.c89
-rw-r--r--src/dynarec/dynarec_native_functions.h4
-rw-r--r--src/dynarec/dynarec_native_pass.c50
-rw-r--r--src/dynarec/dynarec_private.h2
-rw-r--r--src/dynarec/native_lock.h8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_0.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_1.c30
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c90
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c35
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c1402
-rw-r--r--src/dynarec/rv64/dynarec_rv64_64.c53
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c88
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c1686
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f20f.c58
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f30f.c58
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c103
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67_32.c59
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d8.c151
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d9.c40
-rw-r--r--src/dynarec/rv64/dynarec_rv64_da.c164
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c16
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dc.c142
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dd.c33
-rw-r--r--src/dynarec/rv64/dynarec_rv64_de.c40
-rw-r--r--src/dynarec/rv64/dynarec_rv64_df.c24
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_math.c36
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_shift.c12
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c90
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c27
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c219
-rw-r--r--src/dynarec/rv64/dynarec_rv64_functions.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c69
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h1898
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass0.h5
-rw-r--r--src/dynarec/rv64/dynarec_rv64_private.h15
-rw-r--r--src/dynarec/rv64/rv64_emitter.h1158
-rw-r--r--src/dynarec/rv64/rv64_lock.S26
-rw-r--r--src/dynarec/rv64/rv64_lock.h12
-rw-r--r--src/dynarec/rv64/rv64_printer.c755
-rw-r--r--src/elfs/elfload_dump.c4
-rw-r--r--src/elfs/elfloader.c446
-rw-r--r--src/elfs/elfloader_private.h22
-rw-r--r--src/elfs/elfparser.c23
-rw-r--r--src/emu/x64compstrings.c120
-rw-r--r--src/emu/x64compstrings.h13
-rw-r--r--src/emu/x64emu.c2
-rw-r--r--src/emu/x64emu_private.h15
-rw-r--r--src/emu/x64int3.c19
-rw-r--r--src/emu/x64primop.c63
-rw-r--r--src/emu/x64primop.h192
-rw-r--r--src/emu/x64run.c179
-rw-r--r--src/emu/x64run0f.c90
-rw-r--r--src/emu/x64run64.c36
-rw-r--r--src/emu/x64run66.c64
-rw-r--r--src/emu/x64run660f.c166
-rw-r--r--src/emu/x64run66f0.c72
-rw-r--r--src/emu/x64run66f20f.c88
-rw-r--r--src/emu/x64run66f30f.c64
-rw-r--r--src/emu/x64run670f.c9
-rw-r--r--src/emu/x64run6764_32.c24
-rw-r--r--src/emu/x64run_private.c327
-rw-r--r--src/emu/x64run_private.h4
-rw-r--r--src/emu/x64runf0.c66
-rw-r--r--src/emu/x64runf20f.c57
-rw-r--r--src/emu/x64runf30f.c18
-rw-r--r--src/emu/x64shaext.c194
-rw-r--r--src/emu/x64shaext.h18
-rw-r--r--src/emu/x64syscall.c733
-rw-r--r--src/emu/x64test.c4
-rw-r--r--src/emu/x64tls.c5
-rwxr-xr-xsrc/emu/x86syscall.c2
-rw-r--r--src/emu/x87emu_private.h10
-rw-r--r--src/include/box64context.h9
-rw-r--r--src/include/bridge.h3
-rw-r--r--src/include/custommem.h29
-rw-r--r--src/include/debug.h41
-rw-r--r--src/include/elfloader.h6
-rw-r--r--src/include/gtkclass.h1379
-rw-r--r--src/include/librarian.h1
-rw-r--r--src/include/myalign.h22
-rw-r--r--src/include/regs.h46
-rw-r--r--src/include/signals.h1
-rw-r--r--src/include/super80.h82
-rw-r--r--src/include/threads.h1
-rw-r--r--src/librarian/globalsymbols.c4
-rw-r--r--src/librarian/librarian.c148
-rw-r--r--src/librarian/library.c354
-rw-r--r--src/librarian/library_private.h10
-rw-r--r--src/library_list.h150
-rw-r--r--src/libtools/myalign.c2
-rw-r--r--src/libtools/signals.c441
-rw-r--r--src/libtools/threads.c204
-rw-r--r--src/main.c435
-rw-r--r--src/mallochook.c147
-rw-r--r--src/rv64detect.c66
-rw-r--r--src/steam.c128
-rw-r--r--src/tools/bridge.c49
-rw-r--r--src/tools/bridge_private.h4
-rw-r--r--src/tools/callback.c16
-rw-r--r--src/tools/gtkclass.c2451
-rw-r--r--src/tools/my_cpuid.c211
-rw-r--r--src/tools/rcfile.c50
-rw-r--r--src/tools/wine_tools.c2
-rwxr-xr-xsrc/wrapped/wrappedandroidshmem.c18
-rwxr-xr-xsrc/wrapped/wrappedandroidshmem_private.h8
-rw-r--r--src/wrapped/wrappedandroidsupport.c22
-rw-r--r--src/wrapped/wrappedandroidsupport_private.h4
-rw-r--r--src/wrapped/wrappedatomic_private.h8
-rw-r--r--src/wrapped/wrappedayatanaappindicator3.c19
-rw-r--r--src/wrapped/wrappedayatanaappindicator3_private.h45
-rw-r--r--src/wrapped/wrappedcurl.c7
-rw-r--r--src/wrapped/wrappedcurl_private.h1
-rw-r--r--src/wrapped/wrappeddbusmenuglib.c115
-rw-r--r--src/wrapped/wrappeddbusmenuglib_private.h84
-rw-r--r--src/wrapped/wrappedevent21.c71
-rw-r--r--src/wrapped/wrappedevent21_private.h646
-rw-r--r--src/wrapped/wrappedflac.c7
-rw-r--r--src/wrapped/wrappedfontconfig.c12
-rw-r--r--src/wrapped/wrappedfontconfig_private.h4
-rw-r--r--src/wrapped/wrappedfreetype.c8
-rw-r--r--src/wrapped/wrappedfreetype_private.h2
-rw-r--r--src/wrapped/wrappedgbm.c59
-rw-r--r--src/wrapped/wrappedgbm_private.h2
-rw-r--r--src/wrapped/wrappedgdk3.c11
-rw-r--r--src/wrapped/wrappedgdk3_private.h31
-rw-r--r--src/wrapped/wrappedgdkx112.c50
-rw-r--r--src/wrapped/wrappedgdkx112_private.h2
-rw-r--r--src/wrapped/wrappedgio2.c5
-rw-r--r--src/wrapped/wrappedgio2_private.h28
-rw-r--r--src/wrapped/wrappedglib2.c42
-rw-r--r--src/wrapped/wrappedglib2_private.h18
-rw-r--r--src/wrapped/wrappedgnutls.c8
-rw-r--r--src/wrapped/wrappedgobject2.c20
-rw-r--r--src/wrapped/wrappedgobject2_private.h16
-rw-r--r--src/wrapped/wrappedgomp.c55
-rw-r--r--src/wrapped/wrappedgomp_private.h8
-rw-r--r--src/wrapped/wrappedgssapikrb5_private.h10
-rw-r--r--src/wrapped/wrappedgstallocators.c27
-rw-r--r--src/wrapped/wrappedgstallocators_private.h18
-rw-r--r--src/wrapped/wrappedgstapp.c7
-rw-r--r--src/wrapped/wrappedgstaudio.c39
-rw-r--r--src/wrapped/wrappedgstaudio_private.h45
-rw-r--r--src/wrapped/wrappedgstbase.c237
-rw-r--r--src/wrapped/wrappedgstbase_private.h104
-rw-r--r--src/wrapped/wrappedgstcheck.c27
-rw-r--r--src/wrapped/wrappedgstcheck_private.h203
-rw-r--r--src/wrapped/wrappedgstcontroller.c27
-rw-r--r--src/wrapped/wrappedgstcontroller_private.h31
-rw-r--r--src/wrapped/wrappedgstfft.c27
-rw-r--r--src/wrapped/wrappedgstfft_private.h25
-rw-r--r--src/wrapped/wrappedgstgl.c266
-rw-r--r--src/wrapped/wrappedgstgl_private.h324
-rw-r--r--src/wrapped/wrappedgstnet.c27
-rw-r--r--src/wrapped/wrappedgstnet_private.h33
-rw-r--r--src/wrapped/wrappedgstpbutils.c27
-rw-r--r--src/wrapped/wrappedgstpbutils_private.h195
-rw-r--r--src/wrapped/wrappedgstreamer.c699
-rw-r--r--src/wrapped/wrappedgstreamer_private.h341
-rw-r--r--src/wrapped/wrappedgstriff.c22
-rw-r--r--src/wrapped/wrappedgstriff_private.h19
-rw-r--r--src/wrapped/wrappedgstrtp.c27
-rw-r--r--src/wrapped/wrappedgstrtp_private.h215
-rw-r--r--src/wrapped/wrappedgstrtsp.c27
-rw-r--r--src/wrapped/wrappedgstrtsp_private.h170
-rw-r--r--src/wrapped/wrappedgstsdp.c27
-rw-r--r--src/wrapped/wrappedgstsdp_private.h178
-rw-r--r--src/wrapped/wrappedgsttag.c7
-rw-r--r--src/wrapped/wrappedgsttag_private.h8
-rw-r--r--src/wrapped/wrappedgstvideo.c54
-rw-r--r--src/wrapped/wrappedgstvideo_private.h279
-rw-r--r--src/wrapped/wrappedgtk3.c38
-rw-r--r--src/wrapped/wrappedgtk3_private.h800
-rw-r--r--src/wrapped/wrappediconv.c22
-rw-r--r--src/wrapped/wrappediconv_private.h4
-rw-r--r--src/wrapped/wrappedicui18n66.c29
-rw-r--r--src/wrapped/wrappedicui18n66_private.h100
-rw-r--r--src/wrapped/wrappedicuuc66.c28
-rw-r--r--src/wrapped/wrappedicuuc66_private.h86
-rw-r--r--src/wrapped/wrappedkrb5.c7
-rw-r--r--src/wrapped/wrappedlcms2.c18
-rw-r--r--src/wrapped/wrappedlcms2_private.h368
-rw-r--r--src/wrapped/wrappedlib_init.h12
-rw-r--r--src/wrapped/wrappedlibbsd.c34
-rw-r--r--src/wrapped/wrappedlibbsd_private.h112
-rw-r--r--src/wrapped/wrappedlibc.c481
-rw-r--r--src/wrapped/wrappedlibc_private.h192
-rw-r--r--src/wrapped/wrappedlibcups.c9
-rw-r--r--src/wrapped/wrappedlibcups_private.h2
-rw-r--r--src/wrapped/wrappedlibdl.c56
-rw-r--r--src/wrapped/wrappedlibdrm.c29
-rw-r--r--src/wrapped/wrappedlibdrm_private.h63
-rw-r--r--src/wrapped/wrappedlibformw.c3
-rw-r--r--src/wrapped/wrappedlibformw6.c20
-rw-r--r--src/wrapped/wrappedlibformw6_private.h80
-rw-r--r--src/wrapped/wrappedlibgl.c83
-rw-r--r--src/wrapped/wrappedlibgl_private.h12
-rw-r--r--src/wrapped/wrappedlibm.c119
-rw-r--r--src/wrapped/wrappedlibm_private.h24
-rw-r--r--src/wrapped/wrappedlibogg_private.h4
-rw-r--r--src/wrapped/wrappedlibpcre.c5
-rw-r--r--src/wrapped/wrappedlibpthread_private.h2
-rw-r--r--src/wrapped/wrappedlibrt.c88
-rw-r--r--src/wrapped/wrappedlibrt_private.h12
-rw-r--r--src/wrapped/wrappedlibsndfile.c7
-rw-r--r--src/wrapped/wrappedlibusb1.c7
-rw-r--r--src/wrapped/wrappedlibva_private.h6
-rw-r--r--src/wrapped/wrappedlibvorbis.c6
-rw-r--r--src/wrapped/wrappedlibx11.c7
-rw-r--r--src/wrapped/wrappedlibxau.c7
-rw-r--r--src/wrapped/wrappedlibxcb.c7
-rw-r--r--src/wrapped/wrappedlibxcb_private.h10
-rw-r--r--src/wrapped/wrappedlibxcbdri3.c7
-rw-r--r--src/wrapped/wrappedlibxcbglx.c7
-rw-r--r--src/wrapped/wrappedlibxcbicccm.c7
-rw-r--r--src/wrapped/wrappedlibxcbimage.c7
-rw-r--r--src/wrapped/wrappedlibxcbkeysyms.c7
-rw-r--r--src/wrapped/wrappedlibxcbpresent.c7
-rw-r--r--src/wrapped/wrappedlibxcbrandr.c7
-rw-r--r--src/wrapped/wrappedlibxcbrandr_private.h16
-rw-r--r--src/wrapped/wrappedlibxcbrender.c7
-rw-r--r--src/wrapped/wrappedlibxcbrenderutil.c7
-rw-r--r--src/wrapped/wrappedlibxcbshape.c7
-rw-r--r--src/wrapped/wrappedlibxcbshm.c7
-rw-r--r--src/wrapped/wrappedlibxcbsync.c7
-rw-r--r--src/wrapped/wrappedlibxcbutil.c7
-rw-r--r--src/wrapped/wrappedlibxcbxfixes.c7
-rw-r--r--src/wrapped/wrappedlibxcbxinerama.c6
-rw-r--r--src/wrapped/wrappedlibxcbxkb.c7
-rw-r--r--src/wrapped/wrappedlibxcbxtest.c7
-rw-r--r--src/wrapped/wrappedlibxcomposite.c7
-rw-r--r--src/wrapped/wrappedlibxcursor.c7
-rw-r--r--src/wrapped/wrappedlibxdamage.c7
-rw-r--r--src/wrapped/wrappedlibxdmcp.c7
-rw-r--r--src/wrapped/wrappedlibxext.c34
-rw-r--r--src/wrapped/wrappedlibxfixes.c28
-rw-r--r--src/wrapped/wrappedlibxft.c28
-rw-r--r--src/wrapped/wrappedlibxi.c16
-rw-r--r--src/wrapped/wrappedlibxmu.c16
-rw-r--r--src/wrapped/wrappedlibxpm.c16
-rw-r--r--src/wrapped/wrappedlibxpresent.c7
-rw-r--r--src/wrapped/wrappedlibxrandr.c25
-rw-r--r--src/wrapped/wrappedlibxrender.c28
-rw-r--r--src/wrapped/wrappedlibxss.c16
-rw-r--r--src/wrapped/wrappedlibxt.c19
-rw-r--r--src/wrapped/wrappedlibxtst.c19
-rw-r--r--src/wrapped/wrappedlibxxf86vm.c17
-rw-r--r--src/wrapped/wrappedlibz.c7
-rw-r--r--src/wrapped/wrappedmpg123.c8
-rw-r--r--src/wrapped/wrappedopenal.c38
-rw-r--r--src/wrapped/wrappedopencl.c103
-rw-r--r--src/wrapped/wrappedopencl_private.h135
-rw-r--r--src/wrapped/wrappedpng16.c8
-rw-r--r--src/wrapped/wrappedpulse.c602
-rw-r--r--src/wrapped/wrappedpulse_private.h14
-rw-r--r--src/wrapped/wrappedpulsesimple.c16
-rw-r--r--src/wrapped/wrappedsdl1.c2
-rw-r--r--src/wrapped/wrappedsdl2.c5
-rw-r--r--src/wrapped/wrappedsdl2_private.h4
-rw-r--r--src/wrapped/wrappedtcmallocminimal_private.h4
-rw-r--r--src/wrapped/wrappedtermuxexec.c22
-rw-r--r--src/wrapped/wrappedtermuxexec_private.h4
-rw-r--r--src/wrapped/wrappedvorbisfile.c7
-rw-r--r--src/wrapped/wrappedvulkan.c175
-rw-r--r--src/wrapped/wrappedvulkan_private.h41
-rw-r--r--src/wrapped/wrappedwaylandclient_private.h20
-rw-r--r--src/wrapped/wrappedxinerama.c16
-rw-r--r--src/wrapped/wrappedxkbcommon_private.h2
-rw-r--r--src/wrapped/wrappedxshmfence.c7
-rw-r--r--system/box64.box64rc76
-rw-r--r--tests/ref17.txt24
-rw-r--r--tests/ref23.txt1
-rw-r--r--tests/ref24.txt8
-rw-r--r--tests/ref25.txt10
-rw-r--r--tests/ref26.txt640
-rw-r--r--tests/ref27.txt1063
-rw-r--r--tests/ref28.txt31
-rw-r--r--tests/ref29.txt2
-rw-r--r--tests/test17.c5
-rwxr-xr-xtests/test23bin0 -> 15984 bytes
-rw-r--r--tests/test23.c28
-rwxr-xr-xtests/test24bin0 -> 16112 bytes
-rw-r--r--tests/test24.c74
-rwxr-xr-xtests/test25bin0 -> 16048 bytes
-rw-r--r--tests/test25.c47
-rwxr-xr-xtests/test26bin0 -> 40912 bytes
-rw-r--r--tests/test26.c104
-rwxr-xr-xtests/test27bin0 -> 282056 bytes
-rw-r--r--tests/test27.c133
-rwxr-xr-xtests/test28bin0 -> 25008 bytes
-rw-r--r--tests/test28.c134
-rwxr-xr-xtests/test29bin0 -> 16024 bytes
-rw-r--r--tests/test29.c40
344 files changed, 30457 insertions, 8587 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..c407d16
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,14 @@
+---
+BasedOnStyle: WebKit
+AlignTrailingComments: true
+AllowShortBlocksOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: true
+AllowShortIfStatementsOnASingleLine: true
+ColumnLimit: 0
+IndentWidth: 4
+SortIncludes: false
+MaxEmptyLinesToKeep: 2
+IndentCaseLabels: true
+AlignConsecutiveMacros: true
+---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88c8eac..7dcdf06 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,8 @@ SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
option(RPI3ARM64 "Set to ON if targeting an RaspberryPI3 device with multiarch arm64 and armhf" ${RPI3ARM64})
option(RPI4ARM64 "Set to ON if targeting an RaspberryPI4 device with multiarch arm64 and armhf" ${RPI4ARM64})
+option(RPI5ARM64 "Set to ON if targeting an RaspberryPi5 device with multiarch arm64 and armhf" ${RPI5ARM64})
+option(RPI5ARM64PS16K "Set to ON if targeting an RaspberryPi5 device with multiarch arm64, armhf, and 16k pages" ${RPI5ARM64PS16K})
option(RK3326 "Set to ON if targeting an Rockchip RK3326 based device" ${RK3326})
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
option(RK3588 "Set to ON if targeting an Rockchip RK3588(S) based device" ${RK3588})
@@ -15,19 +17,30 @@ option(TEGRAX1 "Set to ON if targeting an Tegra X1 based device" ${TEGRAX1})
option(PHYTIUM "Set to ON if targeting an Phytium (D2000 or FT2000/4) based device" ${PHYTIUM})
option(SD845 "Set to ON if targeting a Snapragon 845 based device" ${SD845})
option(SD888 "Set to ON if targeting a Snapragon 888 based device" ${SD888})
+option(SD8G2 "Set to ON if targeting a Snapragon 8 Gen 2 based device" ${SD8G2})
+option(ADLINK "Set to ON if targeting an ADLink AmpereAltra based device" ${ADLINK})
option(M1 "Set to ON if targeting a AppleM1 running on Asahi computer" ${M1})
option(LARCH64 "Set to ON if targeting an Loongarch64 based device" ${LARCH64})
option(RV64 "Set to ON if targeting an RISC-V RV64GC based device" ${RV64})
option(PPC64LE "Set to ON if targeting an PowerPC 64 LE based device" ${PPC64LE})
option(LX2160A "Set to ON if targeting an LX2160A based device" ${LX2160A})
option(ARM64 "Set to ON if targeting a generic ARM64 based device" ${ARM64})
+option(ANDROID "Set to ON if targeting an Android device" ${ANDROID})
+option(TERMUX "Set to ON if targeting an Android device with Termux" ${TERMUX})
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
+option(SAVE_MEM "Set to ON to build dynarec with some slower memory saving optimisations" ${SAVE_MEM})
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" OFF)
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
option(BAD_SIGNAL "Set to ON to activate the workaround for incoherent si_info on SIGSEGV" ${BAD_SIGNAL})
option(SW64 "Set ON if targeting an SW64 based device" ${SW64})
+option(CI "Set to ON if running in CI" ${CI})
+option(WITH_MOLD "Set to ON to use with mold" ${WITH_MOLD})
+if(TERMUX)
+ set(TERMUX_PATH "/data/data/com.termux/files")
+ set(ANDROID ON CACHE BOOL "")
+endif()
if(LARCH64)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
@@ -48,19 +61,25 @@ if(PPC64LE)
set(RV64_DYNAREC OFF CACHE BOOL "")
set(PAGE16K OFF CACHE BOOL "")
endif()
-if(RK3399 OR RK3588 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RK3326 OR TEGRAX1 OR PHYTIUM OR SD845 OR SD888 OR LX2160A OR M1 OR ARM64)
+if(RPI5ARM64PS16K)
+ set(RPI5ARM64 ON CACHE BOOL "")
+endif()
+if(RK3399 OR RK3588 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RPI5ARM64 OR RK3326 OR TEGRAX1 OR PHYTIUM OR SD845 OR SD888 OR SD8G2 OR LX2160A OR M1 OR ARM64 OR ADLINK)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC ON CACHE BOOL "")
set(RV64_DYNAREC OFF CACHE BOOL "")
endif()
-if(RK3399 OR RK3588 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RK3326 OR TEGRAX1 OR PHYTIUM OR SD845 OR SD888 OR LX2160A)
+if(RK3399 OR RK3588 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RK3326 OR TEGRAX1 OR PHYTIUM OR SD845 OR SD888 OR SD8G2 OR LX2160A OR ADLINK)
set(PAGE16K OFF CACHE BOOL "")
endif()
+if(RK3399 OR ODROIDN2 OR RPI3ARM64 OR RPI4ARM64 OR RPI5ARM64)
+ set(SAVE_MEM ON CACHE BOOL "")
+endif()
if(RK3588)
set(BAD_SIGNAL ON CACHE BOOL "")
endif()
-if(M1 OR LARCH64)
+if(M1 OR LARCH64 OR RPI5ARM64PS16K)
set(PAGE16K ON CACHE BOOL "")
endif()
if(SW64)
@@ -68,6 +87,10 @@ if(SW64)
set(NOALIGN OFF CACHE BOOL "")
set(PAGE8K ON CACHE BOOL "")
endif()
+if(ANDROID)
+ set(NOLOADADDR ON CACHE BOOL "")
+ set(BAD_SIGNAL ON CACHE BOOL "")
+endif()
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
@@ -117,6 +140,11 @@ elseif(RPI4ARM64)
add_definitions(-DRPI4ARM64)
add_definitions(-pipe -march=armv8-a+crc -mtune=cortex-a72)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc -mtune=cortex-a72")
+elseif(RPI5ARM64)
+ add_definitions(-DRPI)
+ add_definitions(-DRPI5ARM64)
+ add_definitions(-pipe -march=armv8.2-a+crc+crypto+fp16+rcpc+dotprod -mtune=cortex-a76)
+ set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+crc+crypto+fp16+rcpc+dotprod -mtune=cortex-a76")
elseif(RK3326)
add_definitions(-DRK3326)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a35+crypto)
@@ -148,8 +176,16 @@ elseif(SD845)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55")
elseif(SD888)
add_definitions(-DSD888)
- add_definitions(-pipe -march=armv8.4-a+crypto)
- set(CMAKE_ASM_FLAGS "-pipe -march=armv8.4-a+crypto")
+ add_definitions(-pipe -march=armv8.4-a+simd+crypto)
+ set(CMAKE_ASM_FLAGS "-pipe -march=armv8.4-a+simd+crypto")
+elseif(SD8G2)
+ add_definitions(-DSD8G2)
+ add_definitions(-pipe -march=armv9-a+i8mm+sm4+sha3+rcpc+crypto+nosve+nosve2)
+ set(CMAKE_ASM_FLAGS "-pipe -march=armv9-a+i8mm+sm4+sha3+rcpc+crypto+nosve+nosve2")
+elseif(ADLINK)
+ add_definitions(-DADLINK)
+ add_definitions(-pipe -mcpu=neoverse-n1 -fuse-ld=gold -fuse-linker-plugin)
+ set(CMAKE_ASM_FLAGS "-pipe -mcpu=neoverse-n1")
elseif(M1)
add_definitions(-DM1)
add_definitions(-pipe -march=armv8.5-a+simd+crypto)
@@ -174,13 +210,22 @@ elseif(ARM64)
#add_definitions(-pipe -march=native)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+simd")
elseif(ARM_DYNAREC)
- set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto")
+ if(NOT ANDROID)
+ set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto")
+ endif()
+endif()
+if(ANDROID)
+ add_definitions(-DANDROID)
+endif()
+if(TERMUX)
+ add_definitions(-DTERMUX)
endif()
-
if(BAD_SIGNAL)
add_definitions(-DBAD_SIGNAL)
endif()
-
+if(SAVE_MEM)
+ add_definitions(-DSAVE_MEM)
+endif()
if(PAGE8K)
add_definitions(-DPAGE8K)
endif()
@@ -268,15 +313,16 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/mallochook.c"
"${BOX64_ROOT}/src/steam.c"
"${BOX64_ROOT}/src/dynarec/dynarec.c"
- "${BOX64_ROOT}/src/elfs/elfdwarf_private.c"
"${BOX64_ROOT}/src/elfs/elfloader.c"
"${BOX64_ROOT}/src/elfs/elfparser.c"
"${BOX64_ROOT}/src/elfs/elfload_dump.c"
+ "${BOX64_ROOT}/src/emu/x64compstrings.c"
"${BOX64_ROOT}/src/emu/x64emu.c"
"${BOX64_ROOT}/src/emu/x64int3.c"
"${BOX64_ROOT}/src/emu/x87emu_private.c"
"${BOX64_ROOT}/src/emu/x64primop.c"
"${BOX64_ROOT}/src/emu/x64run_private.c"
+ "${BOX64_ROOT}/src/emu/x64shaext.c"
"${BOX64_ROOT}/src/emu/x64syscall.c"
"${BOX64_ROOT}/src/emu/x86syscall.c"
"${BOX64_ROOT}/src/emu/x64tls.c"
@@ -287,7 +333,6 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/librarian/globalsymbols.c"
"${BOX64_ROOT}/src/librarian/symbols.c"
"${BOX64_ROOT}/src/libtools/auxval.c"
- "${BOX64_ROOT}/src/libtools/obstack.c"
"${BOX64_ROOT}/src/libtools/myalign.c"
"${BOX64_ROOT}/src/libtools/sdl1rwops.c"
"${BOX64_ROOT}/src/libtools/sdl2rwops.c"
@@ -305,6 +350,12 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/tools/wine_tools.c"
"${BOX64_ROOT}/src/wrapped/generated/wrapper.c"
)
+if(NOT ANDROID)
+ list(APPEND ELFLOADER_SRC
+ "${BOX64_ROOT}/src/libtools/obstack.c"
+ "${BOX64_ROOT}/src/elfs/elfdwarf_private.c"
+ )
+endif()
set(INTERPRETER
"${BOX64_ROOT}/src/emu/x64run.c"
@@ -312,6 +363,8 @@ set(INTERPRETER
"${BOX64_ROOT}/src/emu/x64run64.c"
"${BOX64_ROOT}/src/emu/x64run66.c"
"${BOX64_ROOT}/src/emu/x64run660f.c"
+ "${BOX64_ROOT}/src/emu/x64run66f20f.c"
+ "${BOX64_ROOT}/src/emu/x64run66f30f.c"
"${BOX64_ROOT}/src/emu/x64run6664.c"
"${BOX64_ROOT}/src/emu/x64run66d9.c"
"${BOX64_ROOT}/src/emu/x64run66dd.c"
@@ -342,6 +395,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedatkbridge.c"
"${BOX64_ROOT}/src/wrapped/wrappedatomic.c"
"${BOX64_ROOT}/src/wrapped/wrappedatspi.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedayatanaappindicator3.c"
"${BOX64_ROOT}/src/wrapped/wrappedbz2.c"
"${BOX64_ROOT}/src/wrapped/wrappedcap.c"
"${BOX64_ROOT}/src/wrapped/wrappedcairo.c"
@@ -352,6 +406,8 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedcurl.c"
"${BOX64_ROOT}/src/wrapped/wrappeddbus.c"
"${BOX64_ROOT}/src/wrapped/wrappeddbusglib1.c"
+ "${BOX64_ROOT}/src/wrapped/wrappeddbusmenuglib.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedevent21.c"
"${BOX64_ROOT}/src/wrapped/wrappedexpat.c"
"${BOX64_ROOT}/src/wrapped/wrappedfaudio.c"
"${BOX64_ROOT}/src/wrapped/wrappedflac.c"
@@ -373,19 +429,31 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedgomp.c"
"${BOX64_ROOT}/src/wrapped/wrappedgssapi.c"
"${BOX64_ROOT}/src/wrapped/wrappedgssapikrb5.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstallocators.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstapp.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstaudio.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstbase.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstcheck.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstcontroller.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstfft.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstgl.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstnet.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstpbutils.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstreamer.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstriff.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstrtp.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstrtsp.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedgstsdp.c"
"${BOX64_ROOT}/src/wrapped/wrappedgsttag.c"
"${BOX64_ROOT}/src/wrapped/wrappedgstvideo.c"
"${BOX64_ROOT}/src/wrapped/wrappedgthread2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgtk3.c"
"${BOX64_ROOT}/src/wrapped/wrappedgtkx112.c"
"${BOX64_ROOT}/src/wrapped/wrappedkrb5.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedlcms2.c"
"${BOX64_ROOT}/src/wrapped/wrappedldlinux.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibasound.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedlibbsd.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibc.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibcmusl.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibcrypt.c"
@@ -395,6 +463,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlibegl.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibform.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibformw.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedlibformw6.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibfuse.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibgl.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibglu.c"
@@ -477,6 +546,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappednss3.c"
"${BOX64_ROOT}/src/wrapped/wrappednssutil3.c"
"${BOX64_ROOT}/src/wrapped/wrappedopenal.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedopencl.c"
"${BOX64_ROOT}/src/wrapped/wrappedpango.c"
"${BOX64_ROOT}/src/wrapped/wrappedpangocairo.c"
"${BOX64_ROOT}/src/wrapped/wrappedpangoft2.c"
@@ -525,11 +595,25 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedvulkan.c"
"${BOX64_ROOT}/src/wrapped/wrappedxshmfence.c"
"${BOX64_ROOT}/src/wrapped/wrappedd3dadapter9.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedicuuc66.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedicui18n66.c"
"${BOX64_ROOT}/src/wrapped/wrappedicuuc67.c"
"${BOX64_ROOT}/src/wrapped/wrappedicui18n67.c"
"${BOX64_ROOT}/src/wrapped/wrappedicuuc72.c"
"${BOX64_ROOT}/src/wrapped/wrappedicui18n72.c"
)
+if(ANDROID)
+ list(APPEND WRAPPEDS
+ "${BOX64_ROOT}/src/wrapped/wrappedandroidshmem.c"
+ )
+endif()
+if(TERMUX)
+ list(APPEND WRAPPEDS
+ "${BOX64_ROOT}/src/wrapped/wrappediconv.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedtermuxexec.c"
+ "${BOX64_ROOT}/src/wrapped/wrappedandroidsupport.c"
+ )
+endif()
# If BOX64_ROOT contains a ".c", the build breaks...
string(REPLACE ".c" "_private.h" MODROOT ${BOX64_ROOT})
@@ -544,16 +628,18 @@ endforeach()
set(WRAPPER "${BOX64_ROOT}/src/wrapped/generated/wrapper.c" "${BOX64_ROOT}/src/wrapped/generated/wrapper.h")
-add_custom_command(
- OUTPUT "${BOX64_ROOT}/src/wrapped/generated/functions_list.txt"
- COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/rebuild_wrappers.py"
- "${BOX64_ROOT}"
- "PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "--"
- ${WRAPPEDS_HEAD}
- MAIN_DEPENDENCY "${BOX64_ROOT}/rebuild_wrappers.py"
- DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
- BYPRODUCTS ${WRAPPER}
-)
+if(NOT CI)
+ add_custom_command(
+ OUTPUT "${BOX64_ROOT}/src/wrapped/generated/functions_list.txt"
+ COMMAND "${PYTHON_EXECUTABLE}" "${BOX64_ROOT}/rebuild_wrappers.py"
+ "${BOX64_ROOT}"
+ "PANDORA" "HAVE_LD80BITS" "NOALIGN" "HAVE_TRACE" "ANDROID" "TERMUX" "--"
+ ${WRAPPEDS_HEAD}
+ MAIN_DEPENDENCY "${BOX64_ROOT}/rebuild_wrappers.py"
+ DEPENDS ${WRAPPEDS} ${WRAPPEDS_HEAD}
+ BYPRODUCTS ${WRAPPER}
+ )
+endif ()
#add_custom_command(
# OUTPUT "${BOX64_ROOT}/src/dynarec/last_run.txt"
@@ -601,9 +687,11 @@ if(ARM_DYNAREC)
#"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_65.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_66.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_67.c"
+ "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_67_32.c"
+ "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_6764_32.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_d8.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_d9.c"
- #"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_da.c"
+ "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_da.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_db.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_dc.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_dd.c"
@@ -611,6 +699,8 @@ if(ARM_DYNAREC)
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_df.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_f0.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_660f.c"
+ "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_66f20f.c"
+ "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_66f30f.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_6664.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_66f0.c"
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_f20f.c"
@@ -649,9 +739,10 @@ if(RV64_DYNAREC)
#"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_65.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_66.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_67.c"
+ "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_67_32.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_d8.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_d9.c"
- #"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_da.c"
+ "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_da.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_db.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_dc.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_dd.c"
@@ -659,6 +750,8 @@ if(RV64_DYNAREC)
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_df.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_f0.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_660f.c"
+ "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_66f20f.c"
+ "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_66f30f.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_6664.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_66f0.c"
"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_f20f.c"
@@ -725,7 +818,15 @@ add_dependencies(${BOX64} WRAPPERS)
if(STATICBUILD)
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-static -Wl,--no-as-needed -Wl,--whole-archive -Wl,--allow-multiple-definition -lm -ldl -lrt -lpthread -lresolv -lc -Wl,-defsym,_DYNAMIC=0 -pthread")
else()
- set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,--no-as-needed -lc -lm -ldl -lrt -lpthread -lresolv -Wl,--as-needed -pthread")
+ if(ANDROID)
+ if(TERMUX)
+ target_link_libraries(${BOX64} c m dl android-sysv-semaphore)
+ else()
+ target_link_libraries(${BOX64} c m dl)
+ endif()
+ else()
+ set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,--no-as-needed -lc -lm -ldl -lrt -lpthread -lresolv -Wl,--as-needed -pthread")
+ endif()
endif()
if(DYNAREC)
target_link_libraries(${BOX64} dynarec)
@@ -734,7 +835,7 @@ target_link_libraries(${BOX64} interpreter)
if(${CMAKE_VERSION} VERSION_LESS "3.13")
if(NOT NOLOADADDR)
- if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR WITH_MOLD)
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,--image-base=${BOX64_ELF_ADDRESS}")
else()
set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,-Ttext-segment,${BOX64_ELF_ADDRESS}")
@@ -743,7 +844,7 @@ if(${CMAKE_VERSION} VERSION_LESS "3.13")
else()
# If symbols are missing, try this: target_link_options(${BOX64} PUBLIC -rdynamic)
if(NOT NOLOADADDR)
- if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR WITH_MOLD)
target_link_options(${BOX64} PUBLIC LINKER:--image-base=${BOX64_ELF_ADDRESS})
else()
target_link_options(${BOX64} PUBLIC LINKER:-Ttext-segment,${BOX64_ELF_ADDRESS})
@@ -761,18 +862,42 @@ if(_x86_64 OR _aarch64)
endif()
if(NOT _x86 AND NOT _x86_64)
- install(TARGETS ${BOX64}
+ if(NOT TERMUX)
+ install(TARGETS ${BOX64}
RUNTIME DESTINATION bin)
+ else()
+ install(TARGETS ${BOX64}
+ RUNTIME DESTINATION ${TERMUX_PATH}/usr/bin)
+ endif()
if(NOT NO_CONF_INSTALL)
configure_file(system/box64.conf.cmake system/box64.conf)
- install(FILES ${CMAKE_BINARY_DIR}/system/box64.conf DESTINATION /etc/binfmt.d/)
- install(FILES ${CMAKE_SOURCE_DIR}/system/box64.box64rc DESTINATION /etc/)
+ if(NOT TERMUX)
+ install(FILES ${CMAKE_BINARY_DIR}/system/box64.conf DESTINATION /etc/binfmt.d/)
+ install(FILES ${CMAKE_SOURCE_DIR}/system/box64.box64rc DESTINATION /etc/)
+ else()
+ #install(FILES ${CMAKE_BINARY_DIR}/system/box64.conf DESTINATION ${TERMUX_PATH}/usr/etc/binfmt.d/)
+ install(FILES ${CMAKE_SOURCE_DIR}/system/box64.box64rc DESTINATION ${TERMUX_PATH}/usr/etc/)
+ endif()
+
endif()
if(NOT NO_LIB_INSTALL)
- install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.5 DESTINATION /usr/lib/x86_64-linux-gnu/)
- install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.6 DESTINATION /usr/lib/x86_64-linux-gnu/)
- install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libgcc_s.so.1 DESTINATION /usr/lib/x86_64-linux-gnu/)
- install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libpng12.so.0 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ if(NOT TERMUX)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.5 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.6 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libgcc_s.so.1 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libpng12.so.0 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libcrypto.so.1.1 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libssl.so.1.1 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libunwind.so.8 DESTINATION /usr/lib/x86_64-linux-gnu/)
+ else()
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.5 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.6 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libgcc_s.so.1 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libpng12.so.0 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libcrypto.so.1.1 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libssl.so.1.1 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libunwind.so.8 DESTINATION ${TERMUX_PATH}/usr/lib/x86_64-linux-gnu/)
+ endif()
endif()
endif()
@@ -790,7 +915,11 @@ set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ptitSeb")
set(CPACK_PACKAGE_CONTACT "ptitSeb@box86.org")
set(CPACK_PACKAGE_DESCRIPTION "Box64 - Linux Userspace x86_64 Emulator with a twist")
-set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
+if(NOT TERMUX)
+ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
+else()
+ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libandroid-sysv-semaphore")
+endif()
set(CPACK_PACKAGE_HOMEPAGE_URL, "https://box86.org")
file(STRINGS "${BOX64_ROOT}/src/box64version.h" TEMP_STRING REGEX "BOX64_MAJOR\\s*")
string(REGEX REPLACE "BOX64_MAJOR" "" TEMP_STRING ${TEMP_STRING})
@@ -804,9 +933,15 @@ string(REGEX MATCH "[0-9]" BOX64_REVISION ${TEMP_STRING})
set(CPACK_PACKAGE_VERSION_MAJOR ${BOX64_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${BOX64_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${BOX64_REVISION})
+if(NOT TERMUX)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst")
+endif()
if(_aarch64)
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
+ if(TERMUX)
+ set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "aarch64")
+ else()
+ set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
+ endif()
elseif(__riscv64)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "riscv64")
elseif(_x86_64)
@@ -815,7 +950,14 @@ else()
#probably wrong...
execute_process(COMMAND "dpkg --print-architecture" OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
endif()
-set(CPACK_DEBIAN_FILE_NAME "${BOX64}-${BOX64_MAJOR}.${BOX64_MINOR}.${BOX64_REVISION}_Linux-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
+if(TERMUX)
+set(CPACK_PACKAGING_INSTALL_PREFIX "${TERMUX_PATH}/usr")
+endif()
+if(NOT TERMUX)
+set(CPACK_DEBIAN_FILE_NAME "${BOX64}-${BOX64_MAJOR}.${BOX64_MINOR}.${BOX64_REVISION}_${CMAKE_SYSTEM_NAME}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
+else()
+set(CPACK_DEBIAN_FILE_NAME "${BOX64}-${BOX64_MAJOR}.${BOX64_MINOR}.${BOX64_REVISION}_Termux-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
+endif()
INCLUDE(CPack)
add_test(bootSyscall ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
@@ -922,19 +1064,56 @@ add_test(irelative_reloc ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref20.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
- add_test(longjumpInSignals ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+add_test(longjumpInSignals ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test21 -D TEST_OUTPUT=tmpfile21.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref21.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
- add_test(x87 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+add_test(x87 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test22 -D TEST_OUTPUT=tmpfile22.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref22.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
- set_tests_properties(x87 PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTROUND=0")
+set_tests_properties(x87 PROPERTIES ENVIRONMENT "BOX64_DYNAREC_FASTROUND=0")
+
+add_test(pshufb ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test23 -D TEST_OUTPUT=tmpfile23.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref23.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+add_test(bswap ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test24 -D TEST_OUTPUT=tmpfile24.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref24.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+add_test(x87cache ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test25 -D TEST_OUTPUT=tmpfile25.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref25.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+add_test(feround ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test26 -D TEST_OUTPUT=tmpfile26.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref26.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+set_tests_properties(feround PROPERTIES ENVIRONMENT "BOX64_SYNC_ROUNDING=1")
+
+add_test(sse4_2 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test27 -D TEST_OUTPUT=tmpfile27.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref27.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+add_test(shaext ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test28 -D TEST_OUTPUT=tmpfile28.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref28.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
+add_test(lock ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
+ -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test29 -D TEST_OUTPUT=tmpfile29.txt
+ -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref29.txt
+ -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
+
- file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
+file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
foreach(file ${extension_tests})
get_filename_component(testname "${file}" NAME_WE)
add_test(NAME "${testname}" COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
diff --git a/README.md b/README.md
index a604c05..9966908 100644
--- a/README.md
+++ b/README.md
@@ -37,8 +37,8 @@ Note: Box64's Dynarec uses a mechanism with Memory Protection and a SegFault sig
Compiling/Installation
----
-> Compilation instructions can be found [here](docs/COMPILE.md)\
-> Instructions for installing Wine for Box64 can be found [here](docs/X64WINE.md)
+> Compilation instructions can be found [here](https://github.com/ptitSeb/box64/blob/main/docs/COMPILE.md) \
+> Instructions for installing Wine for Box64 can be found [here](https://github.com/ptitSeb/box64/blob/main/docs/X64WINE.md)
----
@@ -54,7 +54,7 @@ Notes about 32-bit platforms
Because Box64 works by directly translating function calls from x86_64 to host system, the host system (the one Box64 is running on) needs to have 64-bit libraries. Box64 doesn't include any 64-bit <-> 32-bit translation.
-So understand that box64 will only runs 64-bit linux binaries. For 32-bit binaries, you need box86 (with all the multiarch or proot trickery it imply on 64-bit OS).
+So understand that box64 will only run 64-bit linux binaries. For 32-bit binaries, you need box86 (with all the multiarch or proot trickery it implies on a 64-bit OS).
Note that many installer (mojo setup based) will fall back to "x86" when detecting ARM64 OS, and so will try to use box86 for the setup, even if an x86_64 version exist. You can hack your way around with a fake "uname" that return "x86_64" when the argument is "-m"
----
@@ -62,16 +62,16 @@ Note that many installer (mojo setup based) will fall back to "x86" when detecti
Notes about Box64 configuration
----
-Box64 now have configurations files. There are 2 files loaded. `/etc/box4.box64rc` and `~/.box64rc`. Both files have the same syntax, and is basicaly an ini files. Section in square brakets define the process name, and the rest is the env. var. to set. Looke at [Usage](USAGE.md) for detail on what parameters can be put. Box64 comes with a default file that should be installed for better stability. The file in in `system/box64.box64rc` and should be installed to `/etc/box64.box64rc` If, for some reasons, you don't want to install that file here, at least copy it to `~/.box64rc` or some game may not function correctly.
-Note that the priority is: `~/.bashrc` > `/etc/box64.box64rc` > command line
-So, your settings in `~/.bashrc` may override the setting from your command line...
+Box64 now have configurations files. There are 2 files loaded. `/etc/box4.box64rc` and `~/.box64rc`. Both files have the same syntax, and is basicaly an ini files. Section in square brakets define the process name, and the rest is the env. var. to set. Looke at [Usage](USAGE.md) for detail on what parameters can be put. Box64 comes with a default file that should be installed for better stability. The file in in `system/box64.box64rc` and should be installed to `/etc/box64.box64rc` If, for some reason, you don't want to install that file here, at least copy it to `~/.box64rc` or some game may not function correctly.
+Note that the priority is: `~/.box64rc` > `/etc/box64.box64rc` > command line
+So, your settings in `~/.box64rc` may override the setting from your command line...
----
Notes about Unity game emulation
----
-Running Unity games should just works, but you should also note that many Unity3D games require OpenGL 3+ which can be tricky to provide on ARM SBC (single-board computers). Also many newer Unity3D (like KSP) games use the BC7 compressed textures, wich is not supported on many ARM integrated GPU.
+Running Unity games should just work, but you should also note that many Unity3D games require OpenGL 3+ which can be tricky to provide on ARM SBC (single-board computers). Also many newer Unity3D (like KSP) games use the BC7 compressed textures, which is not supported on many ARM integrated GPU.
Hint: on Pi4, use `MESA_GL_VERSION_OVERRIDE=3.2` and with Panfrost use `PAN_MESA_DEBUG=gl3` to use higher profile if the game starts then quits before showing anything.
----
@@ -86,7 +86,7 @@ GTK libraries are now wrapped on box64, both gtk2 and gtk3.
Notes about Steam
----
-Note that Steam is a hybrid 32-bit / 64-bit. You NEED box86 to run Steam, as the client app is a 32-bit binary. It also uses a 64-bit local server binaries, and that steamwebhelper process is now mendatory, even on the "small mode". And that process will eat lots of memory. So machine with less the 6Gb of RAM will need a swapfile tp use Steam.
+Note that Steam is a hybrid 32-bit / 64-bit. You NEED box86 to run Steam, as the client app is a 32-bit binary. It also uses a 64-bit local server binaries, and that steamwebhelper process is now mandatory, even on the "small mode". And that process will eat lots of memory. So machine with less the 6Gb of RAM will need a swapfile to use Steam.
----
@@ -94,14 +94,14 @@ Notes about Wine
----
Wine64 is supported on box64. Proton too. Be aware that 64-bit Wine also includes 32-bit components, to be able to run 32-bit Windows programs. The 32-bit apps will need box86 and will not run without it. On a system where both box64 and box86 are present and working, a wine 64-bit setup can run both 32-bit and 64-bit Windows programs (just use `wine` and `wine64` respectively).
-Note that the new 32bits PE in 64bits process that the Wine time in currently implementing in Wine 7.+ is now supported, but the support is quite young so there might be some residual issues.
+Note that the new 32-bit PE in 64-bit processes that the Wine team is currently implementing in Wine 7.+ is now supported, but the support is quite young so there might be some residual issues.
----
Notes about Vulkan
----
-Box64 wraps Vulkan libraries, but note that it as mostly been tested with a AMD RX550 card and on the Freedreno driver, so some extensions may be missing depending on your graphics card.
+Box64 wraps Vulkan libraries, but note that it as mostly been tested with an AMD RX550 card and on the Freedreno driver, so some extensions may be missing depending on your graphics card.
----
@@ -112,11 +112,11 @@ I want to thank everyone who has contributed to box64 development.
There are many ways to contribute: code contribution, financial, hardware and advertisement!
So, in no particular order, I want to thank:
* For their major code contribution: rajdakin, mogery
- * For their major financial contribution: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
+ * For their major financial contribution: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/), [CubeCoders Limited](http://cubecoders.com/)
* For hardware contribution and LoongArch migration: [xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
* For their major code contribution on the RV64 Dynarec: ksco, xctan
- * For their hardware contribution: [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
- * For their continous advertisement of box64 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
+ * For their hardware contribution: [ADLINK](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en) with [Ampere](https://amperecomputing.com/home/edge), [Radxa](https://rockpi.org/), [StarFive](https://rvspace.org/), [Pine64](https://www.pine64.org/), [AYN](https://www.ayntec.com/)
+ * For their continuous advertisements for the box64 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
And I also thank the many other people who participated even once in this project.
diff --git a/README_CN.md b/README_CN.md
index caeb24e..4403a29 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -14,7 +14,7 @@ Box64 å¯ä»¥åœ¨éž x86_64 Linux 系统(比如 ARM64)上è¿è¡Œ x86_64 Linux ç
由于 Box64 使用一些“系统â€åº“的原生版本,如 libcã€libmã€SDL å’Œ OpenGL 等,因此很容易与大多数应用程åºé›†æˆå’Œä½¿ç”¨ï¼Œå¹¶ä¸”在许多情况下性能会相当ä¸é”™ã€‚å¯ä»¥åœ¨[这里](https://box86.org/index.php/2021/06/game-performances/)查看一些性能测试的样例。
-Box64 集æˆäº†é€‚用于 ARM64 å¹³å°çš„ DynaRec(动æ€é‡ç¼–译器),速度å¯ä»¥æ¯”纯解释模å¼å¿« 5 到 10 å€ã€‚å¯ä»¥åœ¨[这里](https://box86.org/2021/07/inner-workings-a-high%E2%80%91level-view-of-box86-and-a-low%E2%80%91level-view-of-the-dynarec/)找到有关 DynaRec 工作原ç†çš„一些信æ¯ã€‚
+Box64 集æˆäº†é€‚用于 ARM64 å’Œ RV64 å¹³å°çš„ DynaRec(动æ€é‡ç¼–译器),速度å¯ä»¥æ¯”纯解释模å¼å¿« 5 到 10 å€ã€‚å¯ä»¥åœ¨[这里](https://box86.org/2021/07/inner-workings-a-high%E2%80%91level-view-of-box86-and-a-low%E2%80%91level-view-of-the-dynarec/)找到有关 DynaRec 工作原ç†çš„一些信æ¯ã€‚
一些 x64 内部æ“作ç ä½¿ç”¨ “Realmode X86 Emulator Library†的部分内容,有关版æƒè¯¦ç»†ä¿¡æ¯ï¼Œè¯·å‚è§ [x64primop.c](../src/emu/x64primop.c)。
@@ -54,7 +54,7 @@ LOGO ç”± @grayduck 制作,感谢ï¼
因为 Box64 的工作原ç†æ˜¯ç›´æŽ¥å°†å‡½æ•°è°ƒç”¨ä»Ž x86_64 转æ¢ä¸ºä¸»æœºç³»ç»Ÿï¼Œæ‰€ä»¥ä¸»æœºç³»ç»Ÿï¼ˆè¿è¡Œ Box64 的系统)需è¦æœ‰ 64 ä½åº“。Box64 ä¸åŒ…å«ä»»ä½• 64 ä½ <-> 32 ä½çš„转æ¢ã€‚
-所以 box64 åªèƒ½è¿è¡Œ 64 ä½çš„ Linux 二进制。对于 32 ä½äºŒè¿›åˆ¶åˆ™éœ€è¦ä½¿ç”¨ box86 æ¥è¿è¡Œï¼ˆå®ƒåœ¨ 64 ä½æ“作系统上使用了 multiarch å’Œ proot 等技巧æ¥å®žçŽ°è¿è¡Œï¼‰ã€‚请注æ„,许多(基于 mojo 的)安装程åºåœ¨æ£€æµ‹åˆ° ARM64 æ“作系统时将回退到 “x86â€ï¼Œå› æ­¤å³ä½¿å­˜åœ¨ x86_64 版本,也会å°è¯•ä½¿ç”¨ box86。这时你å¯ä»¥ä½¿ç”¨ä¸€ä¸ªå‡çš„ `uname`,当它的å‚数为 `-m` 时返回 `x86_64`。
+所以 box64 åªèƒ½è¿è¡Œ 64 ä½çš„ Linux 二进制。对于 32 ä½äºŒè¿›åˆ¶åˆ™éœ€è¦ä½¿ç”¨ box86 æ¥è¿è¡Œï¼ˆå®ƒåœ¨ 64 ä½æ“作系统上使用了 multiarch å’Œ proot 等技巧æ¥å®žçŽ°è¿è¡Œï¼‰ã€‚请注æ„,许多(基于 mojo 的)安装程åºåœ¨æ£€æµ‹åˆ° ARM64 æ“作系统时将回退到 “x86â€ï¼Œå› æ­¤å³ä½¿å­˜åœ¨ x86_64 版本,也会å°è¯•ä½¿ç”¨ box86。这时你å¯ä»¥ä½¿ç”¨ä¸€ä¸ªå‡çš„ `uname` ,并使它在è¿è¡Œå‚数为 `-m` 时返回 `x86_64`。
----
@@ -77,7 +77,7 @@ box64 å°è£…了 GTK,包括 gtk2 å’Œ gtk3。
关于 Steam 的注æ„事项
----
-请注æ„,Steam 是 32/64 ä½çš„æ··åˆä½“ï¼Œæ‰€ä»¥è¿˜éœ€è¦ box86 æ‰èƒ½è¿è¡Œï¼Œå› ä¸ºå®¢æˆ·ç«¯åº”用程åºæ˜¯ 32 ä½çš„。它还使用 64 ä½æœ¬åœ°æœåŠ¡å™¨ï¼Œä½†ä¸Žå¤§å¤šæ•°ä½¿ç”¨ libcef/chromium 的东西一样,它目å‰æ— æ³•åœ¨ box64 上正常工作。所以,现在 box64 上暂时ä¸èƒ½è¿è¡Œ Steam。
+请注æ„,Steam 是 32/64 ä½æ··åˆçš„åº”ç”¨ï¼Œæ‰€ä»¥ä½ éœ€è¦ box86 æ‰èƒ½è¿è¡Œï¼Œå› ä¸ºå®¢æˆ·ç«¯åº”用程åºæ˜¯ 32 ä½çš„。它还使用 64 ä½æœ¬åœ°æœåŠ¡å™¨ï¼Œå®ƒçš„ steamwebhelper 无法被关闭(å³ä½¿æ˜¯åœ¨æœ€å°æ¨¡å¼ï¼‰è€Œä¸”会åƒæŽ‰å¤§é‡çš„内存。对于内存å°äºŽ 6 GB 的机型,你将会需è¦åˆ›å»º swapfile æ¥è¿è¡Œ Steam。
----
@@ -105,7 +105,7 @@ Box64 å°è£…了 Vulkan 库,但请注æ„,它仅在 RX550 显å¡ä¸Šè¿›è¡Œè¿‡æµ
* 代ç è´¡çŒ®ï¼šrajdakin, mogery
* 财务帮助:FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
* 硬件æèµ å’Œ LoongArch è¿ç§»ï¼š[xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
- * 硬件æ赠:[Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
+ * 硬件æ赠:[ADLink](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en), [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
* 为本项目æŒç»­çš„宣传:salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
我还è¦æ„Ÿè°¢å¾ˆå¤šäººï¼Œå³ä½¿ä»–们åªå‚与了一次本项目。
diff --git a/README_UK.md b/README_UK.md
index a56624e..21bb518 100644
--- a/README_UK.md
+++ b/README_UK.md
@@ -111,7 +111,7 @@ Box64 викориÑтовує бібліотеки Vulkan, але зауважÑ
* За великий фінанÑовий внеÑок: FlyingFathead, stormchaser3000, dennis1248, sll00, [libre-computer-project](https://libre.computer/)
* За апаратне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ñ‚Ð° міграцію LoongArch: [xiaoji](https://www.linuxgame.cn/), команда розробників Deepin Beijing
* За оÑновний внеÑок у код RV64 Dynarec: ksco, xctan
-* За внеÑок у апаратне забезпеченнÑ: [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
+* За внеÑок у апаратне забезпеченнÑ: [ADLink](https://www.adlinktech.com/Products/Computer_on_Modules/COM-HPC-Server-Carrier-and-Starter-Kit/Ampere_Altra_Developer_Platform?lang=en), [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/), [StarFive](https://rvspace.org/)
* За безперервну рекламу Box64: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/Команда [TwisterOS](https://twisteros.com/), [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
І Ñ Ñ‚Ð°ÐºÐ¾Ð¶ дÑкую багатьом іншим людÑм, Ñкі хоч раз брали учаÑÑ‚ÑŒ у цьому проекті.
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 65bbb35..3f4c59f 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,3 +1,31 @@
+v0.2.6
+======
+* X64Libs: Updated libstdc++ & libgcc_s
+* X64Libs: Use x86_64 vrsion of libunwind (it's needed by wine)
+* Dynarec: More opcodes on ARM64 & RV64
+* Dynarec: Fixed some flags propagation issues inside blocks
+* Dynarec: Improved Strong Memory Model emulation, introducing a 3rd level
+* Dynarec: ARM64: reworked shift and bit opcodes flags handling
+* Dynarec: RV64: Many fixes, making Wow64 apps running
+* Dynarec: ARM64: Added support for SSE4.2 (with CRC32 if supported by CPU)
+* Dynarec: ARM64: Added support for SHA (with hardware support if CPU allows it)
+* Dynarec: ARM64: The CALLRET optimisation has been improved and is now default
+* CPU: Remoworked how INT, priviliged opcodes and teh Trace flags works
+* CPU: Added full support for SSE4.2
+* CPU: Added full support for SHA extension
+* ElfLoader: rework how elf memory is handled
+* Emulation: Added some more syscalls
+* Emulation: Better handling of Signal (also handling SIGMAX correctly)
+* Emulation: Better support for POKEUSER/PEEKUSER (helps Windows Unity games)
+* Wrapping: More libs and some fixes in function wrapping (gtk3, vulkan...)
+* Wrapping: Removed faked libunwind wrapping
+* Hardware: Added more profile, with support ADLink Ampere Altra, Qualcomm 8Gen3, and Pi5 machines
+* OS: Added profile to build for Android and Termux.
+* OS: New option to use mold for a high speed link
+=> More hadware support, more functions wrapped for an improve compatibity
+=> More CPU extension, with ARM64 hardware support when possible, and improved CALLRET optimisation for an improved speed of emulation
+=> Some work also to reduce the memory footprint
+
v0.2.4
======
* Added Dynarec for RISC-V
diff --git a/docs/COMPILE.md b/docs/COMPILE.md
index a14292c..dbba30f 100644
--- a/docs/COMPILE.md
+++ b/docs/COMPILE.md
@@ -27,9 +27,9 @@ If it's the first install, you also need:
sudo systemctl restart systemd-binfmt
```
- You can use `make -j1`, `make -j2` to prevent running out of memory
-- You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on Linux Kernel mixed with Android, like on RK3588 or maybe Termux
+- You can also add `-DBAD_SIGNAL=ON` to the cmake command if you are on Linux Kernel mixed with Android, like on RK3588.
-#### For instance, if you want to build box64 for Generic ARM64 Linux platforms, it would look like this:
+#### For Instance, if you want to build box64 for Generic ARM64 Linux platforms, it would look like this:
```
git clone https://github.com/ptitSeb/box64
cd box64
@@ -68,7 +68,6 @@ Still, this can be faster if your build is attended.
```
-D RPI3ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
-make
```
#### for Raspberry Pi 4
@@ -79,6 +78,13 @@ Warning, you need a 64bit OS:
-D RPI4ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
+#### for Raspberry Pi 5
+
+If your Raspberry Pi OS use 16K pages use `RPI5ARM64PS16K` instead of `RPI5ARM64`:
+```
+-D RPI5ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
+```
+
#### for TEGRA X1
Using a 64bit OS:
@@ -96,7 +102,7 @@ Using a 64bit OS:
-D ODROIDN2=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
-#### for Snapdragon 845
+#### for Snapdragon
Using a 64bit OS:
@@ -104,6 +110,14 @@ Using a 64bit OS:
-D SD845=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
+or
+
+```
+-D SD888=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
+```
+
+Depending how recent your Snapdragon is
+
#### for Phytium
Using a 64bit OS:
@@ -111,11 +125,11 @@ Using a 64bit OS:
-D PHYTIUM=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
-#### for a generic ARM64 machine
+#### for ADLink machines
Using a 64bit OS:
```
--D ARM64=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
+-D ADLINK=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
#### for M1
@@ -158,6 +172,26 @@ Using a 64bit OS:
-D LX2160A=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
```
+#### for Termux
+
+You must have ARM64 Device for build box64.
+
+##### in CHRoot/PRoot
+
+```
+-D ARM64=1 -DCMAKE_C_COMPILER=gcc -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
+```
+
+##### in Termux (Native)
+
+NOTE: BUILDING BOX64 IN TERMUX NATIVE IS EXPERIMENTAL AND DOESN'T GONNA RUN LINUX BINARIES IN NATIVE TERMUX BOX64!!!
+
+You also needed have `libandroid-sysv-semaphore` and `libandroid-spawn` libraries:
+
+```
+-D TERMUX=1 -D -DCMAKE_C_COMPILER=clang CMAKE_BUILD_TYPE=RelWithDebInfo
+```
+
#### for x86_64 Linux
```
-D LD80BITS=1 -D NOALIGN=1 -D CMAKE_BUILD_TYPE=RelWithDebInfo
@@ -166,7 +200,7 @@ If you encounter some linking errors, try using `NOLOADADDR=ON` (`cmake -D NOLOA
----
-### use ccmake
+### Use ccmake
Alternatively, you can **use the curses-bases ccmake (or any other gui frontend for cmake)** to select wich platform to use interactively.
@@ -187,12 +221,19 @@ To have a trace enabled build (***the interpreter will be slightly slower***), a
#### To have ARM Dynarec
Dynarec is only available on ARM (for the meantime), Activate it by using `-DARM_DYNAREC=1`.
-###### *Note: VFPv3 and NEON are required for Dynarec.*
+
+#### To have a build using less memory
+
+You can use `-DSAVE_MEM` to have a build that will try to save some memory. It's, for now, only increasing the jumptable from 4 level to 5 levels. The added granularity avoid wasting space, but the 1 level more to the jumptable means there is on read from memory more when jumping between blocks.
#### Not building from a git clone
If you are not building from a git clone (for example, downloading a release source code zip from github), you need to use `-DNOGIT=1` from cmake to be able to build (box64 uses git SHA1 to show last commit in version number).
+#### Use faster linker
+
+You need to add `-DWITH_MOLD=1` if GNU ld is extremely slow. Then run `mold -run make -j4` to build (make sure [Mold](https://github.com/rui314/mold) is installed).
+
----
Testing
diff --git a/docs/USAGE.md b/docs/USAGE.md
index 5c67f0f..ebbc7f8 100644
--- a/docs/USAGE.md
+++ b/docs/USAGE.md
@@ -3,7 +3,10 @@ Usage
----
There are many environment variables to control Box64 behaviour.
-Env. var with * can also be put inside box64rc files
+Env. var with * can also be put inside box64rc files.
+Box64 look for 2 places for rcfile: `/etc/box64.box64rc` and `~/.box64rc`
+The second takes precedence to the first, on an APP level
+(that means if an [MYAPP] my appears in both file, only the settings in `~/.box64rc` will be applied)
#### BOX64_LOG *
Controls the Verbosity level of the logs
@@ -49,7 +52,7 @@ Only on build with trace enabled. Trace allow the logging of all instruction exe
* 0xXXXXXXX-0xYYYYYYY : Trace only between the 2 addresses.
#### BOX64_TRACE_INIT *
-Use BOX64_TRACE_INIT instead of BOX_TRACE to start trace before the initialisation of libraries and the running program
+Use BOX64_TRACE_INIT instead of BOX64_TRACE to start trace before the initialisation of libraries and the running program
* 0 : No trace. (Default.)
* 1 : Trace enabled. The trace start with the initialisation of all depending libraries is done.
@@ -153,8 +156,9 @@ Define Box64's Dynarec max allowed forward value when building Block.
#### BOX64_DYNAREC_STRONGMEM *
Enable/Disable simulation of Strong Memory model
* 0 : Don't try anything special (Default.)
-* 1 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)
-* 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model
+* 1 : Enable some Memory Barrier when writting to memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)
+* 2 : All 1. plus a memory barrier on every write to memory using MOV
+* 3 : All 2. plus Memory Barrier when reading from memory and on some SSE/SSE2 opcodes too
#### BOX64_DYNAREC_X87DOUBLE *
Force the use of Double for x87 emulation
@@ -179,8 +183,8 @@ Handling of flags on CALL/RET opcodes
#### BOX64_DYNAREC_CALLRET *
Optimisation of CALL/RET opcodes (not compatible with jit/dynarec/smc)
-* 0 : Don't optimize CALL/RET, use Jump Table for boths (Default)
-* 1 : Try to optimized CALL/RET, skipping the use of the JumpTable when possible (will crash if blacks are invalidate, so probably incompatible with JIT/Dynarec)
+* 0 : Don't optimize CALL/RET, use Jump Table for boths
+* 1 : Try to optimized CALL/RET, skipping the use of the JumpTable when possible (Default)
#### BOX64_DYNAREC_HOTPAGE *
Handling of HotPage (Page being both executed and written)
@@ -192,6 +196,11 @@ Will use a faster handling of HotPage (Page being both executed and written)
* 0 : use regular hotpage (Default)
* 1 : Use faster hotpage, taking the risk of running obsolete JIT code (might be faster, but more prone to crash)
+#### BOX64_DYNAREC_ALIGNED_ATOMICS *
+Generated code for aligned atomics only
+* 0 : The code generated can handle unaligned atomics (Default)
+* 1 : Generated code only for aligned atomics (faster and less code generated, but will SEGBUS if LOCK prefix is unsed on unaligned data)
+
#### BOX64_DYNAREC_BLEEDING_EDGE *
Detect MonoBleedingEdge and apply conservative settings
* 0 : Don't detect MonoBleedingEdge
@@ -222,11 +231,21 @@ Handling of x87 80bits long double
* 0 : Try to handle 80bits long double as precise as possible (Default)
* 1 : Handle them as double
+#### BOX64_SYNC_ROUNDING *
+Box64 will sync rounding mode with fesetround/fegetround.
+* 0 : Disable rounding mode syncing. (Default.)
+* 1 : Enable rounding mode syncing.
+
#### BOX64_LIBCEF *
Detect libcef and apply malloc_hack settings
* 0 : Don't detect libcef
* 1 : Detect libcef, and apply MALLOC_HACK=2 if detected (Default)
+#### BOX64_SDL2_JGUID *
+Need a workaround for SDL_GetJoystickGUIDInfo function for wrapped SDL2
+* 0 : Don't use any workaround
+* 1 : Use a workaround for program that use the private SDL_GetJoystickGUIDInfo function with 1 missing argument
+
#### BOX64_LIBGL *
* libXXXX set the name for libGL (defaults to libGL.so.1).
* /PATH/TO/libGLXXX : Sets the name and path for libGL
@@ -282,12 +301,17 @@ Disables the load of vulkan libraries.
* 0 : Load vulkan libraries if found.
* 1 : Disables the load of vulkan libraries, both the native and the i386 version (can be useful on Pi4, where the vulkan driver is not quite there yet.)
+#### BOX64_FUTEX_WAITV *
+Use of the new fuext_waitc syscall
+ * 0 : Do not try to use it, return unsupported (Default for BAD_SIGNAL build)
+ * 1 : let program use the syscall if the host system support it (Default for other build)
+
#### BOX64_BASH *
Define x86_64 bash to launch script
* yyyy
Will use yyyy as x86_64 bash to launch script. yyyy needs to be a full path to a valid x86_64 version of bash
-#### BOX64_ENV
+#### BOX64_ENV *
* XXX=yyyy
will add XXX=yyyy env. var.
@@ -295,6 +319,10 @@ Define x86_64 bash to launch script
* XXX=yyyy
will add XXX=yyyy env. var. and continue with BOX86_ENV2 ... until var doesn't exist
+#### BOX64_RESERVE_HIGH
+* 0 : Don't try to pe-reserve high memory (beyond 47bits) (Default)
+* 1 : Try to reserve (without allocating it) memory beyond 47bits (seems unstable)
+
#### BOX64_JITGDB *
* 0 : Just print the Segfault message on segfault (default)
* 1 : Launch `gdb` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process and go in an endless loop, waiting.
@@ -305,6 +333,7 @@ Define x86_64 bash to launch script
* 2 : Launch `gdbserver` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process, and go in an endless loop, waiting.
Use `gdb /PATH/TO/box64` and then `target remote 127.0.0.1:1234` to connect to the gdbserver (or use actual IP if not on the machine). After that, the procedure is the same as with ` BOX64_JITGDB=1`.
This mode can be usefullwhen programs redirect all console output to a file (like Unity3D Games)
+ * 3 : Launch `lldb` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process and go in an endless loop, waiting.
#### BOX64_NORCFILES
If the env var exist, no rc files (like /etc/box64.box64rc and ~/.box64rc) will be loaded
@@ -318,10 +347,10 @@ Those variables are only valid inside a rcfile:
* 0 : Nothing special
* 1 : Added "--no-sandbox" to command line arguments (usefull for chrome based programs)
+#### BOX64_INPROCESSGPU
+ * 0 : Nothing special
+ * 1 : Added "--in-process-gpu" to command line arguments (usefull for chrome based programs)
+
#### BOX64_EXIT
* 0 : Nothing special
* 1 : Just exit, don't try to run the program
-
-#### BOX64_RESERVE_HIGH
-* 0 : Don't try to pe-reserve high memory (beyond 47bits) (Default)
-* 1 : Try to reserve (without allocating it) memory beyond 47bits (seems unstable)
diff --git a/docs/box64.pod b/docs/box64.pod
index b5c89f5..3da39c7 100644
--- a/docs/box64.pod
+++ b/docs/box64.pod
@@ -55,6 +55,11 @@ F<~/.bashrc> may override the setting from your command line. Example:
When set to 1, add C<--no-sandbox> to command line arguments (useful for chrome
based programs).
+=item B<BOX64_INPROCESSGPU=0|1>
+
+When set to 1, add C<--in-process-gpu> to command line arguments (useful for chrome
+based programs).
+
=item B<BOX64_EXIT>=I<0|1>
When set to 1, just exit, don't try to run the program.
@@ -146,7 +151,7 @@ Only on build with trace enabled. Trace allow the logging of all instruction exe
=item B<BOX64_TRACE_INIT>=I<0|1>
-Use B<BOX64_TRACE_INIT> instead of B<BOX_TRACE> to start trace before the
+Use B<BOX64_TRACE_INIT> instead of B<BOX64_TRACE> to start trace before the
initialization of libraries and the running program
* 0 : No trace. (Default.)
@@ -371,6 +376,13 @@ Handling of x87 80bits long double
* 0 : Try to handle 80bits long double as precise as possible (Default)
* 1 : Handle them as double
+=item B<BOX64_SYNC_ROUNDING>=I<0|1>
+
+Box64 will sync rounding mode with fesetround/fegetround.
+
+ * 0 : Disable rounding mode syncing. (Default.)
+ * 1 : Enable rounding mode syncing.
+
=item B<BOX64_LIBCEF>=I<0|1>
Detect libcef and apply malloc_hack settings
@@ -451,6 +463,13 @@ Disables the load of vulkan libraries.
* 0 : Load vulkan libraries if found.
* 1 : Disables the load of vulkan libraries, both the native and the i386 version (can be useful on Pi4, where the vulkan driver is not quite there yet.)
+=item B<BOX64_FUTEX_WAITV>=I<0|1>
+
+Use of the new fuext_waitc syscall
+
+ * 0 : Do not try to use it, return unsupported (default for BAD_SIGNAL build)
+ * 1 : let program use the syscall if the host system support it (Default for other build)
+
=item B<BOX64_BASH>=I<yyyy>
Define x86_64 bash to launch script. Will use yyyy as x86_64 bash to launch
diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py
index 0bd25f0..e22c52d 100755
--- a/rebuild_wrappers.py
+++ b/rebuild_wrappers.py
@@ -402,6 +402,7 @@ def readFiles(files: Iterable[Filename]) -> Tuple[JumbledGlobals, JumbledRedirec
or match("libGL", "libEGL") \
or match("libc", "tcmallocminimal") \
or match("libc", "tbbmallocproxy") \
+ or match("libc", "androidshmem") \
or match("tcmallocminimal", "tbbmallocproxy"):
continue
diff --git a/runTest.cmake b/runTest.cmake
index 11ab75f..e9a5a46 100644
--- a/runTest.cmake
+++ b/runTest.cmake
@@ -11,6 +11,9 @@ endif( NOT TEST_OUTPUT )
if( NOT TEST_REFERENCE )
message( FATAL_ERROR "Require TEST_REFERENCE to be defined" )
endif( NOT TEST_REFERENCE )
+if(NOT DEFINED ENV{INTERPRETER})
+ set(ENV{INTERPRETER} "")
+endif()
set(ENV{BOX64_LOG} 0)
set(ENV{BOX64_NOBANNER} 1)
@@ -24,7 +27,7 @@ endif( EXISTS ${CMAKE_SOURCE_DIR}/x64lib )
# run the test program, capture the stdout/stderr and the result var
execute_process(
- COMMAND ${TEST_PROGRAM} ${TEST_ARGS} ${TEST_ARGS2}
+ COMMAND $ENV{INTERPRETER} ${TEST_PROGRAM} ${TEST_ARGS} ${TEST_ARGS2}
OUTPUT_FILE ${TEST_OUTPUT}
ERROR_VARIABLE TEST_ERROR
RESULT_VARIABLE TEST_RESULT
diff --git a/src/box64context.c b/src/box64context.c
index 234657c..b302b77 100644
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -68,6 +68,8 @@ void free_tlsdatasize(void* p)
tlsdatasize_t *data = (tlsdatasize_t*)p;
box_free(data->ptr);
box_free(p);
+ if(my_context)
+ pthread_setspecific(my_context->tlskey, NULL);
}
void x64Syscall(x64emu_t *emu);
@@ -278,6 +280,7 @@ void FreeBox64Context(box64context_t** context)
box64context_t* ctx = *context; // local copy to do the cleanning
+ //clean_current_emuthread(); // cleaning main thread seems a bad idea
if(ctx->local_maplib)
FreeLibrarian(&ctx->local_maplib, NULL);
if(ctx->maplib)
@@ -342,7 +345,6 @@ void FreeBox64Context(box64context_t** context)
void* ptr;
if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) {
free_tlsdatasize(ptr);
- pthread_setspecific(ctx->tlskey, NULL);
}
pthread_key_delete(ctx->tlskey);
diff --git a/src/box64version.h b/src/box64version.h
index ea108de..e9cf508 100644
--- a/src/box64version.h
+++ b/src/box64version.h
@@ -3,6 +3,6 @@
#define BOX64_MAJOR 0
#define BOX64_MINOR 2
-#define BOX64_REVISION 4
+#define BOX64_REVISION 6
#endif //__BOX64_VERSION_H_
diff --git a/src/custommem.c b/src/custommem.c
index a92f983..7e73a23 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -30,12 +30,18 @@
#include "dynarec/native_lock.h"
#include "dynarec/dynarec_next.h"
-//#define USE_MMAP
+#define USE_MMAP
// init inside dynablocks.c
static mmaplist_t *mmaplist = NULL;
static uint64_t jmptbl_allocated = 0, jmptbl_allocated1 = 0, jmptbl_allocated2 = 0, jmptbl_allocated3 = 0;
+#ifdef JMPTABL_SHIFT4
+static uint64_t jmptbl_allocated4 = 0;
+static uintptr_t**** box64_jmptbl4[1<<JMPTABL_SHIFT4];
+static uintptr_t*** box64_jmptbldefault3[1<<JMPTABL_SHIFT3];
+#else
static uintptr_t*** box64_jmptbl3[1<<JMPTABL_SHIFT3];
+#endif
static uintptr_t** box64_jmptbldefault2[1<<JMPTABL_SHIFT2];
static uintptr_t* box64_jmptbldefault1[1<<JMPTABL_SHIFT1];
static uintptr_t box64_jmptbldefault0[1<<JMPTABL_SHIFT0];
@@ -73,11 +79,13 @@ typedef struct memprot_s
uint8_t* prot;
uint8_t* hot;
} memprot_t;
+//#define TRACE_MEMSTAT
#ifdef TRACE_MEMSTAT
static uint64_t memprot_allocated = 0, memprot_max_allocated = 0;
#endif
static memprot_t memprot[1<<MEMPROT_SIZE0]; // x86_64 mem is 48bits, page is 12bits, so memory is tracked as [20][16][page protection]
static uint8_t memprot_default[MEMPROT_SIZE];
+static int have48bits = 0;
static int inited = 0;
typedef struct mapmem_s {
@@ -85,7 +93,8 @@ typedef struct mapmem_s {
struct mapmem_s *next;
} mapmem_t;
-static mapmem_t *mapmem = NULL;
+static mapmem_t *mapallmem = NULL;
+static mapmem_t *mmapmem = NULL;
typedef struct blocklist_s {
void* block;
@@ -94,7 +103,7 @@ typedef struct blocklist_s {
void* first;
} blocklist_t;
-#define MMAPSIZE (256*1024) // allocate 256kb sized blocks
+#define MMAPSIZE (64*1024) // allocate 64b sized blocks
static int n_blocks = 0; // number of blocks for custom malloc
static int c_blocks = 0; // capacity of blocks for custom malloc
@@ -478,6 +487,62 @@ void customFree(void* p)
}
#ifdef DYNAREC
+#define GET_PROT_WAIT(A, B) \
+ uint32_t A; \
+ do { \
+ A = native_lock_xchg_b(&block[B], PROT_WAIT); \
+ } while(A==PROT_WAIT)
+#define GET_PROT(A, B) \
+ uint32_t A; \
+ do { \
+ A = native_lock_get_b(&block[B]); \
+ } while(A==PROT_WAIT)
+
+#define SET_PROT(A, B) native_lock_storeb(&block[A], B)
+#define LOCK_NODYNAREC()
+#define UNLOCK_DYNAREC() mutex_unlock(&mutex_prot)
+#define UNLOCK_NODYNAREC()
+static uint8_t* getProtBlock(uintptr_t idx, int fill)
+{
+ uint8_t* block = (uint8_t*)native_lock_get_dd(&memprot[idx].prot);
+ if(fill && block==memprot_default) {
+ uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t));
+ if(native_lock_storeifref(&memprot[idx].prot, newblock, memprot_default)==newblock)
+ {
+ block = newblock;
+#ifdef TRACE_MEMSTAT
+ memprot_allocated += (1<<16) * sizeof(uint8_t);
+ if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated;
+#endif
+ } else {
+ box_free(newblock);
+ }
+ }
+ return block;
+}
+#else
+#define GET_PROT_WAIT(A, B) uint32_t A = block[B]
+#define GET_PROT(A, B) uint32_t A = block[B]
+#define SET_PROT(A, B) block[A] = B
+#define LOCK_NODYNAREC() mutex_lock(&mutex_prot)
+#define UNLOCK_DYNAREC()
+#define UNLOCK_NODYNAREC() mutex_unlock(&mutex_prot)
+static uint8_t* getProtBlock(uintptr_t idx, int fill)
+{
+ uint8_t* block = memprot[idx].prot;
+ if(fill && block==memprot_default) {
+ block = box_calloc(1<<16, sizeof(uint8_t));
+ memprot[idx].prot = block;
+#ifdef TRACE_MEMSTAT
+ memprot_allocated += (1<<16) * sizeof(uint8_t);
+ if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated;
+#endif
+ }
+ return block;
+}
+#endif
+
+#ifdef DYNAREC
#define NCHUNK 64
typedef struct mmaplist_s {
blocklist_t chunks[NCHUNK];
@@ -630,18 +695,35 @@ void FreeDynarecMap(uintptr_t addr)
static uintptr_t getDBSize(uintptr_t addr, size_t maxsize, dynablock_t** db)
{
+ #ifdef JMPTABL_START4
+ const uintptr_t idx4 = (addr>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
const uintptr_t idx3 = (addr>>JMPTABL_START3)&JMPTABLE_MASK3;
const uintptr_t idx2 = (addr>>JMPTABL_START2)&JMPTABLE_MASK2;
const uintptr_t idx1 = (addr>>JMPTABL_START1)&JMPTABLE_MASK1;
uintptr_t idx0 = addr&JMPTABLE_MASK0;
+ #ifdef JMPTABL_START4
+ *db = *(dynablock_t**)(box64_jmptbl4[idx4][idx3][idx2][idx1][idx0]- sizeof(void*));
+ #else
*db = *(dynablock_t**)(box64_jmptbl3[idx3][idx2][idx1][idx0]- sizeof(void*));
+ #endif
if(*db)
return addr+1;
+ #ifdef JMPTABL_START4
+ if(box64_jmptbl4[idx4] == box64_jmptbldefault3)
+ return ((idx4+1)<<JMPTABL_START4);
+ if(box64_jmptbl4[idx4][idx3] == box64_jmptbldefault2)
+ return (((addr>>JMPTABL_START3)+1)<<JMPTABL_START3);
+ if(box64_jmptbl4[idx4][idx3][idx2] == box64_jmptbldefault1)
+ return (((addr>>JMPTABL_START2)+1)<<JMPTABL_START2);
+ uintptr_t* block = box64_jmptbl4[idx4][idx3][idx2][idx1];
+ #else
if(box64_jmptbl3[idx3] == box64_jmptbldefault2)
return ((idx3+1)<<JMPTABL_START3);
if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1)
return (((addr>>JMPTABL_START2)+1)<<JMPTABL_START2);
uintptr_t* block = box64_jmptbl3[idx3][idx2][idx1];
+ #endif
if(block == box64_jmptbldefault0)
return (((addr>>JMPTABL_START1)+1)<<JMPTABL_START1);
maxsize+=idx0; // need to adjust maxsize to "end in current block"
@@ -681,6 +763,64 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy)
}
}
+#ifdef JMPTABL_SHIFT4
+static uintptr_t *create_jmptbl(uintptr_t idx0, uintptr_t idx1, uintptr_t idx2, uintptr_t idx3, uintptr_t idx4)
+{
+ if(box64_jmptbl4[idx4] == box64_jmptbldefault3) {
+ uintptr_t**** tbl = (uintptr_t****)box_malloc((1<<JMPTABL_SHIFT3)*sizeof(uintptr_t***));
+ for(int i=0; i<(1<<JMPTABL_SHIFT3); ++i)
+ tbl[i] = box64_jmptbldefault2;
+ if(native_lock_storeifref(&box64_jmptbl4[idx4], tbl, box64_jmptbldefault3)!=tbl)
+ box_free(tbl);
+#ifdef TRACE_MEMSTAT
+ else {
+ jmptbl_allocated += (1<<JMPTABL_SHIFT3)*sizeof(uintptr_t***);
+ ++jmptbl_allocated4;
+ }
+#endif
+ }
+ if(box64_jmptbl4[idx4][idx3] == box64_jmptbldefault2) {
+ uintptr_t*** tbl = (uintptr_t***)box_malloc((1<<JMPTABL_SHIFT2)*sizeof(uintptr_t**));
+ for(int i=0; i<(1<<JMPTABL_SHIFT2); ++i)
+ tbl[i] = box64_jmptbldefault1;
+ if(native_lock_storeifref(&box64_jmptbl4[idx4][idx3], tbl, box64_jmptbldefault2)!=tbl)
+ box_free(tbl);
+#ifdef TRACE_MEMSTAT
+ else {
+ jmptbl_allocated += (1<<JMPTABL_SHIFT2)*sizeof(uintptr_t**);
+ ++jmptbl_allocated3;
+ }
+#endif
+ }
+ if(box64_jmptbl4[idx4][idx3][idx2] == box64_jmptbldefault1) {
+ uintptr_t** tbl = (uintptr_t**)box_malloc((1<<JMPTABL_SHIFT1)*sizeof(uintptr_t*));
+ for(int i=0; i<(1<<JMPTABL_SHIFT1); ++i)
+ tbl[i] = box64_jmptbldefault0;
+ if(native_lock_storeifref(&box64_jmptbl4[idx4][idx3][idx2], tbl, box64_jmptbldefault1)!=tbl)
+ box_free(tbl);
+#ifdef TRACE_MEMSTAT
+ else {
+ jmptbl_allocated += (1<<JMPTABL_SHIFT1)*sizeof(uintptr_t*);
+ ++jmptbl_allocated2;
+ }
+#endif
+ }
+ if(box64_jmptbl4[idx4][idx3][idx2][idx1] == box64_jmptbldefault0) {
+ uintptr_t* tbl = (uintptr_t*)box_malloc((1<<JMPTABL_SHIFT0)*sizeof(uintptr_t));
+ for(int i=0; i<(1<<JMPTABL_SHIFT0); ++i)
+ tbl[i] = (uintptr_t)native_next;
+ if(native_lock_storeifref(&box64_jmptbl4[idx4][idx3][idx2][idx1], tbl, box64_jmptbldefault0)!=tbl)
+ box_free(tbl);
+#ifdef TRACE_MEMSTAT
+ else {
+ jmptbl_allocated += (1<<JMPTABL_SHIFT0)*sizeof(uintptr_t);
+ ++jmptbl_allocated1;
+ }
+#endif
+ }
+ return &box64_jmptbl4[idx4][idx3][idx2][idx1][idx0];
+}
+#else
static uintptr_t *create_jmptbl(uintptr_t idx0, uintptr_t idx1, uintptr_t idx2, uintptr_t idx3)
{
if(box64_jmptbl3[idx3] == box64_jmptbldefault2) {
@@ -724,20 +864,36 @@ static uintptr_t *create_jmptbl(uintptr_t idx0, uintptr_t idx1, uintptr_t idx2,
}
return &box64_jmptbl3[idx3][idx2][idx1][idx0];
}
+#endif
int addJumpTableIfDefault64(void* addr, void* jmp)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4;
+ idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0;
+ #ifdef JMPTABL_SHIFT4
+ return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3, idx4), jmp, native_next)==jmp)?1:0;
+ #else
return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3), jmp, native_next)==jmp)?1:0;
+ #endif
}
void setJumpTableDefault64(void* addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4;
+ idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ if(box64_jmptbl4[idx4] == box64_jmptbldefault3)
+ return;
+ uintptr_t ****box64_jmptbl3 = box64_jmptbl4[idx4];
+ #endif
idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
if(box64_jmptbl3[idx3] == box64_jmptbldefault2)
return;
@@ -748,11 +904,18 @@ void setJumpTableDefault64(void* addr)
if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0)
return;
idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0;
- box64_jmptbl3[idx3][idx2][idx1][idx0] = (uintptr_t)native_next;
+ native_lock_store_dd(&box64_jmptbl3[idx3][idx2][idx1][idx0], (uintptr_t)native_next);
}
void setJumpTableDefaultRef64(void* addr, void* jmp)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4;
+ idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ if(box64_jmptbl4[idx4] == box64_jmptbldefault3)
+ return;
+ uintptr_t ****box64_jmptbl3 = box64_jmptbl4[idx4];
+ #endif
idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
if(box64_jmptbl3[idx3] == box64_jmptbldefault2)
return;
@@ -768,15 +931,29 @@ void setJumpTableDefaultRef64(void* addr, void* jmp)
int setJumpTableIfRef64(void* addr, void* jmp, void* ref)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0;
+ #ifdef JMPTABL_SHIFT4
+ return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3, idx4), jmp, ref)==jmp)?1:0;
+ #else
return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3), jmp, ref)==jmp)?1:0;
+ #endif
}
int isJumpTableDefault64(void* addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4;
+ idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ if(box64_jmptbl4[idx4] == box64_jmptbldefault3)
+ return 1;
+ uintptr_t ****box64_jmptbl3 = box64_jmptbl4[idx4];
+ #endif
idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
if(box64_jmptbl3[idx3] == box64_jmptbldefault2)
return 1;
@@ -791,37 +968,45 @@ int isJumpTableDefault64(void* addr)
}
uintptr_t getJumpTable64()
{
+ #ifdef JMPTABL_SHIFT4
+ return (uintptr_t)box64_jmptbl4;
+ #else
return (uintptr_t)box64_jmptbl3;
+ #endif
}
uintptr_t getJumpTableAddress64(uintptr_t addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = ((addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = ((addr) )&JMPTABLE_MASK0;
+ #ifdef JMPTABL_SHIFT4
+ return (uintptr_t)create_jmptbl(idx0, idx1, idx2, idx3, idx4);
+ #else
return (uintptr_t)create_jmptbl(idx0, idx1, idx2, idx3);
+ #endif
}
dynablock_t* getDB(uintptr_t addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = ((addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = ((addr) )&JMPTABLE_MASK0;
- /*if(box64_jmptbl3[idx3] == box64_jmptbldefault2) {
- return NULL;
- }
- if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) {
- return NULL;
- }
- if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) {
- return NULL;
- }*/
-
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t ret = (uintptr_t)box64_jmptbl4[idx4][idx3][idx2][idx1][idx0];
+ #else
uintptr_t ret = (uintptr_t)box64_jmptbl3[idx3][idx2][idx1][idx0];
+ #endif
return *(dynablock_t**)(ret - sizeof(void*));
}
@@ -829,11 +1014,18 @@ dynablock_t* getDB(uintptr_t addr)
int getNeedTest(uintptr_t addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = ((addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = ((addr) )&JMPTABLE_MASK0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t ret = (uintptr_t)box64_jmptbl4[idx4][idx3][idx2][idx1][idx0];
+ #else
uintptr_t ret = (uintptr_t)box64_jmptbl3[idx3][idx2][idx1][idx0];
+ #endif
dynablock_t* db = *(dynablock_t**)(ret - sizeof(void*));
return db?((ret!=(uintptr_t)db->block)?1:0):0;
}
@@ -841,11 +1033,18 @@ int getNeedTest(uintptr_t addr)
uintptr_t getJumpAddress64(uintptr_t addr)
{
uintptr_t idx3, idx2, idx1, idx0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t idx4 = (((uintptr_t)addr)>>JMPTABL_START4)&JMPTABLE_MASK4;
+ #endif
idx3 = ((addr)>>JMPTABL_START3)&JMPTABLE_MASK3;
idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2;
idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1;
idx0 = ((addr) )&JMPTABLE_MASK0;
+ #ifdef JMPTABL_SHIFT4
+ return (uintptr_t)box64_jmptbl4[idx4][idx3][idx2][idx1][idx0];
+ #else
return (uintptr_t)box64_jmptbl3[idx3][idx2][idx1][idx0];
+ #endif
}
// Remove the Write flag from an adress range, so DB can be executed safely
@@ -858,33 +1057,32 @@ void protectDB(uintptr_t addr, uintptr_t size)
end = (1LL<<(48-MEMPROT_SHIFT))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
- mutex_lock(&mutex_prot);
int ret;
- for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
- if(memprot[i].prot==memprot_default) {
- uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t));
- memprot[i].prot = newblock;
-#ifdef TRACE_MEMSTAT
- memprot_allocated += (1<<16) * sizeof(uint8_t);
- if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated;
-#endif
- }
+ uintptr_t bidx = ~1LL;
+ uint8_t* block = NULL;
for (uintptr_t i=idx; i<=end; ++i) {
- uint32_t prot = memprot[i>>16].prot[i&0xffff];
+ if(i>>16!=bidx) {
+ bidx = i>>16;
+ block = getProtBlock(bidx, 1);
+ }
+ uint32_t prot;
+ do {
+ prot = native_lock_xchg_b(&block[i&0xffff], PROT_WAIT);
+ } while(prot==PROT_WAIT);
uint32_t dyn = prot&PROT_DYN;
- uint32_t mapped = prot&PROT_MMAP;
if(!prot)
prot = PROT_READ | PROT_WRITE | PROT_EXEC; // comes from malloc & co, so should not be able to execute
prot&=~PROT_CUSTOM;
if(!(dyn&PROT_NOPROT)) {
if(prot&PROT_WRITE) {
- if(!dyn) mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
- memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC; // need to use atomic exchange?
- } else
- memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC_R;
+ if(!dyn)
+ mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
+ prot |= PROT_DYNAREC;
+ } else
+ prot |= PROT_DYNAREC_R;
}
+ native_lock_storeb(&block[i&0xffff], prot);
}
- mutex_unlock(&mutex_prot);
}
// Add the Write flag from an adress range, and mark all block as dirty
@@ -898,25 +1096,27 @@ void unprotectDB(uintptr_t addr, size_t size, int mark)
end = (1LL<<(48-MEMPROT_SHIFT))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
- mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
- if(memprot[i>>16].prot==memprot_default) {
+ uint8_t* block = getProtBlock(i>>16, 0);
+ if(block == memprot_default) {
i=(((i>>16)+1)<<16)-1; // next block
} else {
- uint32_t prot = memprot[i>>16].prot[i&0xffff];
+ uint32_t prot;
+ do {
+ prot = native_lock_xchg_b(&block[i&0xffff], PROT_WAIT);
+ } while(prot==PROT_WAIT);
if(!(prot&PROT_NOPROT)) {
if(prot&PROT_DYNAREC) {
prot&=~PROT_DYN;
if(mark)
cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0);
- mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_MMAP);
- memprot[i>>16].prot[i&0xffff] = prot; // need to use atomic exchange?
+ mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot);
} else if(prot&PROT_DYNAREC_R)
- memprot[i>>16].prot[i&0xffff] = prot&~PROT_CUSTOM;
+ prot &= ~PROT_CUSTOM;
}
+ native_lock_storeb(&block[i&0xffff], prot);
}
}
- mutex_unlock(&mutex_prot);
}
int isprotectedDB(uintptr_t addr, size_t size)
@@ -931,7 +1131,11 @@ int isprotectedDB(uintptr_t addr, size_t size)
return 0;
}
for (uintptr_t i=idx; i<=end; ++i) {
- uint32_t prot = memprot[i>>16].prot[i&0xffff];
+ uint8_t* block = getProtBlock(i>>16, 0);
+ uint32_t prot;
+ do {
+ prot = native_lock_get_b(&block[i&0xffff]);
+ } while(prot==PROT_WAIT);
if(!(prot&PROT_DYN)) {
dynarec_log(LOG_DEBUG, "0\n");
return 0;
@@ -943,7 +1147,7 @@ int isprotectedDB(uintptr_t addr, size_t size)
#endif
-void printMapMem()
+void printMapMem(mapmem_t* mapmem)
{
mapmem_t* m = mapmem;
while(m) {
@@ -952,10 +1156,12 @@ void printMapMem()
}
}
-void addMapMem(uintptr_t begin, uintptr_t end)
+void addMapMem(mapmem_t* mapmem, uintptr_t begin, uintptr_t end)
{
if(!mapmem)
return;
+ if(begin<box64_pagesize)
+ begin = box64_pagesize;
begin &=~(box64_pagesize-1);
end = (end&~(box64_pagesize-1))+(box64_pagesize-1); // full page
// sanitize values
@@ -991,10 +1197,12 @@ void addMapMem(uintptr_t begin, uintptr_t end)
}
// all done!
}
-void removeMapMem(uintptr_t begin, uintptr_t end)
+void removeMapMem(mapmem_t* mapmem, uintptr_t begin, uintptr_t end)
{
if(!mapmem)
return;
+ if(begin<box64_pagesize)
+ begin = box64_pagesize;
begin &=~(box64_pagesize-1);
end = (end&~(box64_pagesize-1))+(box64_pagesize-1); // full page
// sanitize values
@@ -1045,20 +1253,17 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
if(end>=(1LL<<(48-MEMPROT_SHIFT)))
end = (1LL<<(48-MEMPROT_SHIFT))-1;
mutex_lock(&mutex_prot);
- addMapMem(addr, addr+size-1);
- for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
- if(memprot[i].prot==memprot_default) {
- uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t));
- memprot[i].prot = newblock;
-#ifdef TRACE_MEMSTAT
- memprot_allocated += (1<<16) * sizeof(uint8_t);
- if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated;
-#endif
- }
+ addMapMem(mapallmem, addr, addr+size-1);
+ UNLOCK_DYNAREC();
+ uintptr_t bidx = ~1LL;
+ uint8_t *block = NULL;
for (uintptr_t i=idx; i<=end; ++i) {
- uint32_t old_prot = memprot[i>>16].prot[i&0xffff];
+ if(bidx!=i>>16) {
+ bidx = i>>16;
+ block = getProtBlock(bidx, 1);
+ }
+ GET_PROT_WAIT(old_prot, i&0xffff);
uint32_t dyn=(old_prot&PROT_DYN);
- uint32_t mapped=(old_prot&PROT_MMAP);
if(!(dyn&PROT_NOPROT)) {
if(dyn && (prot&PROT_WRITE)) { // need to remove the write protection from this block
dyn = PROT_DYNAREC;
@@ -1067,9 +1272,9 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
dyn = PROT_DYNAREC_R;
}
}
- memprot[i>>16].prot[i&0xffff] = prot|dyn|mapped;
+ SET_PROT(i&0xffff, prot|dyn);
}
- mutex_unlock(&mutex_prot);
+ UNLOCK_NODYNAREC();
}
void setProtection(uintptr_t addr, size_t size, uint32_t prot)
@@ -1079,49 +1284,59 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot)
if(end>=(1LL<<(48-MEMPROT_SHIFT)))
end = (1LL<<(48-MEMPROT_SHIFT))-1;
mutex_lock(&mutex_prot);
- addMapMem(addr, addr+size-1);
+ addMapMem(mapallmem, addr, addr+size-1);
+ UNLOCK_DYNAREC();
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i) {
- if(memprot[i].prot==memprot_default && prot) {
- uint8_t* newblock = box_calloc(MEMPROT_SIZE, sizeof(uint8_t));
- memprot[i].prot = newblock;
-#ifdef TRACE_MEMSTAT
- memprot_allocated += (1<<16) * sizeof(uint8_t);
- if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated;
-#endif
- }
- if(prot || memprot[i].prot!=memprot_default) {
+ uint8_t* block = getProtBlock(i, prot?1:0);
+ if(prot || block!=memprot_default) {
uintptr_t bstart = ((i<<16)<idx)?(idx&0xffff):0;
uintptr_t bend = (((i<<16)+0xffff)>end)?(end&0xffff):0xffff;
for (uintptr_t j=bstart; j<=bend; ++j)
- memprot[i].prot[j] = prot;
+ SET_PROT(j, prot);
}
}
- mutex_unlock(&mutex_prot);
+ UNLOCK_NODYNAREC();
}
void setProtection_mmap(uintptr_t addr, size_t size, uint32_t prot)
{
+ if(!size)
+ return;
+ size = (size+box64_pagesize-1)&~(box64_pagesize-1); // round size
+ mutex_lock(&mutex_prot);
+ addMapMem(mmapmem, addr, addr+size-1);
+ mutex_unlock(&mutex_prot);
if(prot)
- setProtection(addr, size, prot|PROT_MMAP);
+ setProtection(addr, size, prot);
else {
mutex_lock(&mutex_prot);
- addMapMem(addr, addr+size-1);
+ addMapMem(mapallmem, addr, addr+size-1);
+ mutex_unlock(&mutex_prot);
+ }
+}
+
+void setProtection_elf(uintptr_t addr, size_t size, uint32_t prot)
+{
+ if(prot)
+ setProtection(addr, size, prot);
+ else {
+ mutex_lock(&mutex_prot);
+ addMapMem(mapallmem, addr, addr+size-1);
mutex_unlock(&mutex_prot);
}
}
void refreshProtection(uintptr_t addr)
{
- mutex_lock(&mutex_prot);
+ LOCK_NODYNAREC();
uintptr_t idx = (addr>>MEMPROT_SHIFT);
- if(memprot[idx>>16].prot!=memprot_default) {
- int prot = memprot[idx>>16].prot[idx&0xffff];
- if(!(prot&PROT_DYNAREC)) {
- int ret = mprotect((void*)(idx<<MEMPROT_SHIFT), box64_pagesize, prot&~PROT_CUSTOM);
+ uint8_t* block = getProtBlock(idx>>16, 0);
+ if(block!=memprot_default) {
+ GET_PROT(prot, idx&0xffff);
+ int ret = mprotect((void*)(idx<<MEMPROT_SHIFT), box64_pagesize, prot&~PROT_CUSTOM);
printf_log(LOG_INFO, "refreshProtection(%p): %p/0x%x (ret=%d/%s)\n", (void*)addr, (void*)(idx<<MEMPROT_SHIFT), prot, ret, ret?strerror(errno):"ok");
- }
}
- mutex_unlock(&mutex_prot);
+ UNLOCK_NODYNAREC();
}
void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
@@ -1132,24 +1347,9 @@ void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
if(end>=(1LL<<(48-MEMPROT_SHIFT)))
end = (1LL<<(48-MEMPROT_SHIFT))-1;
mutex_lock(&mutex_prot);
- addMapMem(addr, addr+size-1);
- // don't need to add precise tracking probably
- /*for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
- if(memprot[i].prot==memprot_default) {
- uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t));
- memprot[i].prot = newblock;
- }
- for (uintptr_t i=idx; i<=end; ++i) {
- const uintptr_t start = i&(MEMPROT_SIZE-1);
- const uintptr_t finish = (((i|(MEMPROT_SIZE-1))<end)?(MEMPROT_SIZE-1):end)&(MEMPROT_SIZE-1);
- uint8_t* block = memprot[i>>16].prot;
- for(uintptr_t ii = start; ii<=finish; ++ii) {
- if(!block[ii])
- block[ii] = prot;
- }
- i+=finish-start; // +1 from the "for" loop
- }*/
+ addMapMem(mapallmem, addr, addr+size-1);
mutex_unlock(&mutex_prot);
+ // don't need to add precise tracking probably
}
#ifdef DYNAREC
@@ -1157,7 +1357,7 @@ int IsInHotPage(uintptr_t addr) {
if(addr>=(1LL<<48))
return 0;
int idx = (addr>>MEMPROT_SHIFT)>>16;
- uint8_t *hot = memprot[idx].hot;
+ uint8_t *hot = (uint8_t*)native_lock_get_dd(&memprot[idx].hot);
if(!hot)
return 0;
int base = (addr>>MEMPROT_SHIFT)&0xffff;
@@ -1178,7 +1378,7 @@ int AreaInHotPage(uintptr_t start, uintptr_t end_) {
}
int ret = 0;
for (uintptr_t i=idx; i<=end; ++i) {
- uint8_t *block = memprot[i>>16].hot;
+ uint8_t *block = (uint8_t*)native_lock_get_dd(&memprot[i>>16].hot);
int base = i&0xffff;
if(block) {
uint32_t hot = block[base];
@@ -1231,8 +1431,18 @@ void loadProtectionFromMap()
if(sscanf(buf, "%lx-%lx %c%c%c", &s, &e, &r, &w, &x)==5) {
int prot = ((r=='r')?PROT_READ:0)|((w=='w')?PROT_WRITE:0)|((x=='x')?PROT_EXEC:0);
allocProtection(s, e-s, prot);
+ if(s>0x7fff00000000LL)
+ have48bits = 1;
}
}
+ static int shown48bits = 0;
+ if(!shown48bits) {
+ shown48bits = 1;
+ if(have48bits)
+ printf_log(LOG_INFO, "BOX64: Detected 48bits at least of address space\n");
+ else
+ printf_log(LOG_INFO, "BOX64: Didn't detect 48bits of address space, considering it's 39bits\n");
+ }
fclose(f);
box64_mapclean = 1;
}
@@ -1254,20 +1464,33 @@ void freeProtection(uintptr_t addr, size_t size)
if(end>=(1LL<<(48-MEMPROT_SHIFT)))
end = (1LL<<(48-MEMPROT_SHIFT))-1;
mutex_lock(&mutex_prot);
- removeMapMem(addr, addr+size-1);
+ removeMapMem(mapallmem, addr, addr+size-1);
+ removeMapMem(mmapmem, addr, addr+size-1);
+ UNLOCK_DYNAREC();
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>16);
const uintptr_t start = i&(MEMPROT_SIZE-1);
const uintptr_t finish = (((i|(MEMPROT_SIZE-1))<end)?(MEMPROT_SIZE-1):end)&(MEMPROT_SIZE-1);
- if(memprot[key].prot!=memprot_default) {
- uint8_t *block = memprot[key].prot;
+ if(getProtBlock(key, 0)!=memprot_default) {
if(start==0 && finish==MEMPROT_SIZE-1) {
+ #ifdef DYNAREC
+ uint8_t *block = (uint8_t*)native_lock_xchg_dd(&memprot[key].prot, (uintptr_t)memprot_default);
+ #else
+ uint8_t *block = memprot[key].prot;
memprot[key].prot = memprot_default;
- box_free(block);
+ #endif
+ if(block!=memprot_default) {
+ box_free(block);
#ifdef TRACE_MEMSTAT
- memprot_allocated -= (1<<16) * sizeof(uint8_t);
+ memprot_allocated -= (1<<16) * sizeof(uint8_t);
#endif
+ }
} else {
+ #ifdef DYNAREC
+ uint8_t *block = (uint8_t*)native_lock_get_dd(&memprot[key].prot);
+ #else
+ uint8_t *block = memprot[key].prot;
+ #endif
memset(block+start, 0, (finish-start+1)*sizeof(uint8_t));
// blockempty is quite slow, so disable the free of blocks for now
/*else if(blockempty(block)) {
@@ -1276,58 +1499,77 @@ void freeProtection(uintptr_t addr, size_t size)
}*/
}
}
+ #ifdef DYNAREC
+ if(native_lock_get_dd(&memprot[key].hot) && start==0 && finish==MEMPROT_SIZE-1) {
+ uint8_t *hot = (uint8_t*)native_lock_xchg_dd(&memprot[key].hot, 0);
+ if(hot) {
+ box_free(hot);
+#ifdef TRACE_MEMSTAT
+ memprot_allocated -= (1<<16) * sizeof(uint8_t);
+#endif
+ }
+ }
+ #else
if(memprot[key].hot && start==0 && finish==MEMPROT_SIZE-1) {
- uint8_t *hot = memprot[key].hot;
+ box_free(memprot[key].hot);
memprot[key].hot = NULL;
- box_free(hot);
#ifdef TRACE_MEMSTAT
memprot_allocated -= (1<<16) * sizeof(uint8_t);
#endif
}
+ #endif
i+=finish-start; // +1 from the "for" loop
}
- mutex_unlock(&mutex_prot);
+ UNLOCK_NODYNAREC();
}
uint32_t getProtection(uintptr_t addr)
{
if(addr>=(1LL<<48))
return 0;
- mutex_lock(&mutex_prot);
+ LOCK_NODYNAREC();
const uintptr_t idx = (addr>>MEMPROT_SHIFT);
- uint32_t ret = memprot[idx>>16].prot[idx&0xffff];
- mutex_unlock(&mutex_prot);
- return ret&~PROT_MMAP;
+ uint8_t *block = getProtBlock(idx>>16, 0);
+ GET_PROT(ret, idx&0xffff);
+ UNLOCK_NODYNAREC();
+ return ret;
}
int getMmapped(uintptr_t addr)
{
- if(addr>=(1LL<<48))
- return 0;
- mutex_lock(&mutex_prot);
- const uintptr_t idx = (addr>>MEMPROT_SHIFT);
- uint32_t ret = memprot[idx>>16].prot[idx&0xffff];
- mutex_unlock(&mutex_prot);
- return (ret&PROT_MMAP)?1:0;
+ mapmem_t* m = mmapmem;
+ if(addr<box64_pagesize) return 0;
+ while(m) {
+ uintptr_t begin = m->begin;
+ uintptr_t end = m->end;
+ if(addr>=begin && addr<=end)
+ return 1;
+ if(addr<begin)
+ return 0;
+ m = m->next;
+ }
+ return 0;
}
#define LOWEST (void*)0x10000
-#define MEDIUM (void*)0x20000000
+#define MEDIUM (void*)0x40000000
-void* find31bitBlockNearHint(void* hint, size_t size)
+void* find31bitBlockNearHint(void* hint, size_t size, uintptr_t mask)
{
- mapmem_t* m = mapmem;
+ mapmem_t* m = mapallmem;
uintptr_t h = (uintptr_t)hint;
if(hint<LOWEST) hint = LOWEST;
+ if(!mask) mask = 0xffff;
while(m && m->end<0x80000000LL) {
// granularity 0x10000
- uintptr_t addr = (m->end+1+0xffff)&~0xffff;
+ uintptr_t addr = m->end+1;
uintptr_t end = (m->next)?(m->next->begin-1):0xffffffffffffffffLL;
// check hint and available size
if(addr<=h && end>=h && end-h+1>=size)
return hint;
- if(addr>=h && end-addr+1>=size)
- return (void*)addr;
+ uintptr_t aaddr = (addr+mask)&~mask;
+ if(aaddr>=h && end>aaddr && end-aaddr+1>=size)
+ return (void*)aaddr;
m = m->next;
}
return NULL;
@@ -1335,37 +1577,73 @@ void* find31bitBlockNearHint(void* hint, size_t size)
void* find32bitBlock(size_t size)
{
- void* ret = find31bitBlockNearHint(MEDIUM, size);
+ void* ret = find31bitBlockNearHint(MEDIUM, size, 0);
if(ret)
return ret;
- ret = find31bitBlockNearHint(LOWEST, size);
+ ret = find31bitBlockNearHint(LOWEST, size, 0);
return ret?ret:find47bitBlock(size);
}
void* find47bitBlock(size_t size)
{
- void* ret = find47bitBlockNearHint((void*)0x100000000LL, size);
+ void* ret = find47bitBlockNearHint((void*)0x100000000LL, size, 0);
if(!ret)
ret = find32bitBlock(size);
return ret;
}
-void* find47bitBlockNearHint(void* hint, size_t size)
+void* find47bitBlockNearHint(void* hint, size_t size, uintptr_t mask)
{
- mapmem_t* m = mapmem;
+ mapmem_t* m = mapallmem;
uintptr_t h = (uintptr_t)hint;
if(hint<LOWEST) hint = LOWEST;
+ if(!mask) mask = 0xffff;
while(m && m->end<0x800000000000LL) {
// granularity 0x10000
- uintptr_t addr = (m->end+1+0xffff)&~0xffff;
+ uintptr_t addr = m->end+1;
uintptr_t end = (m->next)?(m->next->begin-1):0xffffffffffffffffLL;
// check hint and available size
if(addr<=h && end>=h && end-h+1>=size)
return hint;
- if(addr>=h && end-addr+1>=size)
- return (void*)addr;
+ uintptr_t aaddr = (addr+mask)&~mask;
+ if(aaddr>=h && end>aaddr && end-aaddr+1>=size)
+ return (void*)aaddr;
m = m->next;
}
return NULL;
}
+void* find47bitBlockElf(size_t size, int mainbin, uintptr_t mask)
+{
+ static void* startingpoint = NULL;
+ if(!startingpoint) {
+ startingpoint = (void*)(have48bits?0x7fff00000000LL:0x3f00000000LL);
+ }
+ void* mainaddr = (void*)0x100000000LL;
+ void* ret = find47bitBlockNearHint(mainbin?mainaddr:startingpoint, size, mask);
+ if(!ret)
+ ret = find31bitBlockNearHint(MEDIUM, size, mask);
+ if(!ret)
+ ret = find31bitBlockNearHint(LOWEST, size, mask);
+ if(!mainbin)
+ startingpoint = (void*)(((uintptr_t)startingpoint+size+0x1000000LL)&~0xffffffLL);
+ return ret;
+}
+
+int isBlockFree(void* hint, size_t size)
+{
+ mapmem_t* m = mapallmem;
+ uintptr_t h = (uintptr_t)hint;
+ if(h>0x800000000000LL)
+ return 0; // no tracking there
+ while(m && m->end<0x800000000000LL) {
+ uintptr_t addr = m->end+1;
+ uintptr_t end = (m->next)?(m->next->begin-1):0xffffffffffffffffLL;
+ if(addr<=h && end>=h && end-h+1>=size)
+ return 1;
+ if(addr>h)
+ return 0;
+ m = m->next;
+ }
+ return 0;
+}
int unlockCustommemMutex()
{
@@ -1427,10 +1705,14 @@ static void atfork_child_custommem(void)
void reserveHighMem()
{
char* p = getenv("BOX64_RESERVE_HIGH");
+ #if 0//def ADLINK
+ if(p && p[0]=='0')
+ #else
if(!p || p[0]=='0')
+ #endif
return; // don't reserve by default
intptr_t cur = 1LL<<47;
- mapmem_t* m = mapmem;
+ mapmem_t* m = mapallmem;
while(m && (m->end<cur)) {
m = m->next;
}
@@ -1448,7 +1730,7 @@ void reserveHighMem()
cur = m->end + 1;
m = m->next;
if(addr)
- addMapMem(addr, end);
+ addMapMem(mapallmem, addr, end);
}
}
@@ -1464,8 +1746,15 @@ void init_custommem_helper(box64context_t* ctx)
init_mutexes();
#ifdef DYNAREC
if(box64_dynarec) {
+ #ifdef JMPTABL_SHIFT4
+ for(int i=0; i<(1<<JMPTABL_SHIFT4); ++i)
+ box64_jmptbl4[i] = box64_jmptbldefault3;
+ for(int i=0; i<(1<<JMPTABL_SHIFT3); ++i)
+ box64_jmptbldefault3[i] = box64_jmptbldefault2;
+ #else
for(int i=0; i<(1<<JMPTABL_SHIFT3); ++i)
box64_jmptbl3[i] = box64_jmptbldefault2;
+ #endif
for(int i=0; i<(1<<JMPTABL_SHIFT2); ++i)
box64_jmptbldefault2[i] = box64_jmptbldefault1;
for(int i=0; i<(1<<JMPTABL_SHIFT1); ++i)
@@ -1476,12 +1765,16 @@ void init_custommem_helper(box64context_t* ctx)
lockaddress = kh_init(lockaddress);
#endif
pthread_atfork(NULL, NULL, atfork_child_custommem);
- // init mapmem list
- mapmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t));
- mapmem->begin = 0x0;
- mapmem->end = (uintptr_t)LOWEST - 1;
+ // init mapallmem list
+ mapallmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t));
+ mapallmem->begin = 0x0;
+ mapallmem->end = (uintptr_t)LOWEST - 1;
loadProtectionFromMap();
reserveHighMem();
+ // init mmapmem list
+ mmapmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t));
+ mmapmem->begin = 0x0;
+ mmapmem->end = (uintptr_t)box64_pagesize - 1;
// check if PageSize is correctly defined
if(box64_pagesize != (1<<MEMPROT_SHIFT)) {
printf_log(LOG_NONE, "Error: PageSize configuration is wrong: configured with %d, but got %zd\n", 1<<MEMPROT_SHIFT, box64_pagesize);
@@ -1494,9 +1787,15 @@ void fini_custommem_helper(box64context_t *ctx)
(void)ctx;
#ifdef TRACE_MEMSTAT
uintptr_t njmps = 0, njmps_in_lv1_max = 0;
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t**** box64_jmptbl3;
+ for(uintptr_t idx4 = 0; idx4 < (1<< JMPTABL_SHIFT4); ++idx4) {
+ if (box64_jmptbl4[idx4] == box64_jmptbldefault3) continue;
+ box64_jmptbl3 = box64_jmptbl4[idx4];
+ #endif
for (uintptr_t idx3 = 0; idx3 < (1 << JMPTABL_SHIFT3); ++idx3) {
if (box64_jmptbl3[idx3] == box64_jmptbldefault2) continue;
- for (uintptr_t idx2 = 0; idx2 < (1 << JMPTABL_SHIFT3); ++idx2) {
+ for (uintptr_t idx2 = 0; idx2 < (1 << JMPTABL_SHIFT2); ++idx2) {
if (box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) continue;
for (uintptr_t idx1 = 0; idx1 < (1 << JMPTABL_SHIFT1); ++idx1) {
if (box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) continue;
@@ -1510,7 +1809,12 @@ void fini_custommem_helper(box64context_t *ctx)
}
}
}
- printf_log(LOG_INFO, "Allocation:\n- dynarec: %lld kio\n- customMalloc: %lld kio\n- memprot: %lld kio (peak at %lld kio)\n- jump table: %lld kio (%lld level 3, %lld level 2, %lld level 1 table allocated, for %lld jumps, with at most %lld per level 1)\n", dynarec_allocated / 1024, customMalloc_allocated / 1024, memprot_allocated / 1024, memprot_max_allocated / 1024, jmptbl_allocated / 1024, jmptbl_allocated3, jmptbl_allocated2, jmptbl_allocated1, njmps, njmps_in_lv1_max);
+ #ifdef JMPTABL_SHIFT4
+ }
+ if(box64_log) printf("Allocation:\n- dynarec: %lld kio\n- customMalloc: %lld kio\n- memprot: %lld kio (peak at %lld kio)\n- jump table: %lld kio (%lld level 4, %lld level 3, %lld level 2, %lld level 1 table allocated, for %lld jumps, with at most %lld per level 1)\n", dynarec_allocated / 1024, customMalloc_allocated / 1024, memprot_allocated / 1024, memprot_max_allocated / 1024, jmptbl_allocated / 1024, jmptbl_allocated4, jmptbl_allocated3, jmptbl_allocated2, jmptbl_allocated1, njmps, njmps_in_lv1_max);
+ #else
+ if(box64_log) printf("Allocation:\n- dynarec: %lld kio\n- customMalloc: %lld kio\n- memprot: %lld kio (peak at %lld kio)\n- jump table: %lld kio (%lld level 3, %lld level 2, %lld level 1 table allocated, for %lld jumps, with at most %lld per level 1)\n", dynarec_allocated / 1024, customMalloc_allocated / 1024, memprot_allocated / 1024, memprot_max_allocated / 1024, jmptbl_allocated / 1024, jmptbl_allocated3, jmptbl_allocated2, jmptbl_allocated1, njmps, njmps_in_lv1_max);
+ #endif
#endif
if(!inited)
return;
@@ -1535,6 +1839,12 @@ void fini_custommem_helper(box64context_t *ctx)
}
box_free(mmaplist);
+ #ifdef JMPTABL_SHIFT4
+ uintptr_t**** box64_jmptbl3;
+ for(int i4 = 0; i4 < (1<< JMPTABL_SHIFT4); ++i4)
+ if (box64_jmptbl4[i4] != box64_jmptbldefault3) {
+ box64_jmptbl3 = box64_jmptbl4[i4];
+ #endif
for (int i3=0; i3<(1<<JMPTABL_SHIFT3); ++i3)
if(box64_jmptbl3[i3]!=box64_jmptbldefault2) {
for (int i2=0; i2<(1<<JMPTABL_SHIFT2); ++i2)
@@ -1547,6 +1857,10 @@ void fini_custommem_helper(box64context_t *ctx)
}
box_free(box64_jmptbl3[i3]);
}
+ #ifdef JMPTABL_SHIFT4
+ box_free(box64_jmptbl4[i4]);
+ }
+ #endif
}
kh_destroy(lockaddress, lockaddress);
lockaddress = NULL;
@@ -1572,9 +1886,14 @@ void fini_custommem_helper(box64context_t *ctx)
pthread_mutex_destroy(&mutex_prot);
pthread_mutex_destroy(&mutex_blocks);
#endif
- while(mapmem) {
- mapmem_t *tmp = mapmem;
- mapmem = mapmem->next;
+ while(mapallmem) {
+ mapmem_t *tmp = mapallmem;
+ mapallmem = mapallmem->next;
+ box_free(tmp);
+ }
+ while(mmapmem) {
+ mapmem_t *tmp = mmapmem;
+ mmapmem = mmapmem->next;
box_free(tmp);
}
}
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 02ba209..cbfa837 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -92,24 +92,24 @@
// MOVZ
#define MOVZ_gen(sf, hw, imm16, Rd) ((sf)<<31 | 0b10<<29 | 0b100101<<23 | (hw)<<21 | (imm16)<<5 | (Rd))
-#define MOVZx(Rd, imm16) EMIT(MOVZ_gen(1, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVZx_LSL(Rd, imm16, shift) EMIT(MOVZ_gen(1, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVZw(Rd, imm16) EMIT(MOVZ_gen(0, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVZw_LSL(Rd, imm16, shift) EMIT(MOVZ_gen(0, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
+#define MOVZx(Rd, imm16) EMIT(MOVZ_gen(1, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVZx_LSL(Rd, imm16, shift) EMIT(MOVZ_gen(1, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVZw(Rd, imm16) EMIT(MOVZ_gen(0, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVZw_LSL(Rd, imm16, shift) EMIT(MOVZ_gen(0, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
// MOVN
#define MOVN_gen(sf, hw, imm16, Rd) ((sf)<<31 | 0b00<<29 | 0b100101<<23 | (hw)<<21 | (imm16)<<5 | (Rd))
-#define MOVNx(Rd, imm16) EMIT(MOVN_gen(1, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVNx_LSL(Rd, imm16, shift) EMIT(MOVN_gen(1, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVNw(Rd, imm16) EMIT(MOVN_gen(0, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVNw_LSL(Rd, imm16, shift) EMIT(MOVN_gen(0, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
+#define MOVNx(Rd, imm16) EMIT(MOVN_gen(1, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVNx_LSL(Rd, imm16, shift) EMIT(MOVN_gen(1, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVNw(Rd, imm16) EMIT(MOVN_gen(0, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVNw_LSL(Rd, imm16, shift) EMIT(MOVN_gen(0, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
// MOVK
#define MOVK_gen(sf, hw, imm16, Rd) ((sf)<<31 | 0b11<<29 | 0b100101<<23 | (hw)<<21 | (imm16)<<5 | (Rd))
-#define MOVKx(Rd, imm16) EMIT(MOVK_gen(1, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVKx_LSL(Rd, imm16, shift) EMIT(MOVK_gen(1, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVKw(Rd, imm16) EMIT(MOVK_gen(0, 0, ((uint16_t)imm16)&0xffff, Rd))
-#define MOVKw_LSL(Rd, imm16, shift) EMIT(MOVK_gen(0, (shift)/16, ((uint16_t)imm16)&0xffff, Rd))
+#define MOVKx(Rd, imm16) EMIT(MOVK_gen(1, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVKx_LSL(Rd, imm16, shift) EMIT(MOVK_gen(1, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVKw(Rd, imm16) EMIT(MOVK_gen(0, 0, ((uint16_t)(imm16))&0xffff, Rd))
+#define MOVKw_LSL(Rd, imm16, shift) EMIT(MOVK_gen(0, (shift)/16, ((uint16_t)(imm16))&0xffff, Rd))
// This macro will give a -Wsign-compare warning, probably bug #38341
#define MOV32w(Rd, imm32) \
@@ -200,6 +200,12 @@
#define SBCSw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(0, 1, 1, Rm, Rn, Rd))
#define SBCSxw_REG(Rd, Rn, Rm) EMIT(ADDSUBC_gen(rex.w, 1, 1, Rm, Rn, Rd))
+// CCMP compare if cond is true, set nzcv if false
+#define CCMP_reg(sf, Rm, cond, Rn, nzcv) ((sf)<<31 | 1<<30 | 1<<29 | 0b11010010<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (nzcv))
+#define CCMPw(Wn, Wm, nzcv, cond) EMIT(CCMP_reg(0, Wm, cond, Wn, nzcv))
+#define CCMPx(Xn, Xm, nzcv, cond) EMIT(CCMP_reg(1, Xm, cond, Xn, nzcv))
+#define CCMPxw(Xn, Xm, nzcv, cond) EMIT(CCMP_reg(rex.w, Xm, cond, Xn, nzcv))
+
// ADR
#define ADR_gen(immlo, immhi, Rd) ((immlo)<<29 | 0b10000<<24 | (immhi)<<5 | (Rd))
#define ADR_S20(Rd, imm) EMIT(ADR_gen((imm)&3, ((imm)>>2)&0x7ffff, (Rd)))
@@ -240,6 +246,7 @@
#define LDRxw_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b011, 0, Rn, Rt))
#define LDRz_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(rex.is32bits?0b10:0b11, Rm, 0b011, 0, Rn, Rt))
#define LDRB_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt))
+#define LDRB_REG_UXTW(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b010, 0, Rn, Rt))
#define LDRH_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt))
#define LDRS_U12_gen(size, op1, opc, imm12, Rn, Rt) ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt))
@@ -427,6 +434,13 @@
// Data Memory Barrier
#define DMB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b01<<5 | 0b11111)
#define DMB_ISH() EMIT(DMB_gen(0b1011))
+#define DMB_SY() EMIT(DMB_gen(0b1111))
+
+// Data Synchronization Barrier
+#define DSB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b00<<5 | 0b11111)
+#define DSB_ISH() EMIT(DSB_gen(0b1011))
+#define DSB_ISHST() EMIT(DSB_gen(0b1010))
+#define DSB_SY() EMIT(DSB_gen(0b1111))
// Break
#define BRK_gen(imm16) (0b11010100<<24 | 0b001<<21 | (((imm16)&0xffff)<<5))
@@ -593,12 +607,12 @@
#define BFMx(Rd, Rn, immr, imms) EMIT(BFM_gen(1, 0b01, 1, immr, imms, Rn, Rd))
#define BFMw(Rd, Rn, immr, imms) EMIT(BFM_gen(0, 0b01, 0, immr, imms, Rn, Rd))
#define BFMxw(Rd, Rn, immr, imms) EMIT(BFM_gen(rex.w, 0b01, rex.w, immr, imms, Rn, Rd))
-#define BFIx(Rd, Rn, lsb, width) BFMx(Rd, Rn, ((-lsb)%64)&0x3f, (width)-1)
-#define BFIw(Rd, Rn, lsb, width) BFMw(Rd, Rn, ((-lsb)%32)&0x1f, (width)-1)
+#define BFIx(Rd, Rn, lsb, width) BFMx(Rd, Rn, ((-(lsb))%64)&0x3f, (width)-1)
+#define BFIw(Rd, Rn, lsb, width) BFMw(Rd, Rn, ((-(lsb))%32)&0x1f, (width)-1)
#define BFIxw(Rd, Rn, lsb, width) if(rex.w) {BFIx(Rd, Rn, lsb, width);} else {BFIw(Rd, Rn, lsb, width);}
-#define BFCx(Rd, lsb, width) BFMx(Rd, xZR, ((-lsb)%64)&0x3f, (width)-1)
-#define BFCw(Rd, lsb, width) BFMw(Rd, xZR, ((-lsb)%32)&0x1f, (width)-1)
-#define BFCxw(Rd, lsb, width) BFMxw(Rd, xZR, rex.w?(((-lsb)%64)&0x3f):(((-lsb)%32)&0x1f), (width)-1)
+#define BFCx(Rd, lsb, width) BFMx(Rd, xZR, ((-(lsb))%64)&0x3f, (width)-1)
+#define BFCw(Rd, lsb, width) BFMw(Rd, xZR, ((-(lsb))%32)&0x1f, (width)-1)
+#define BFCxw(Rd, lsb, width) BFMxw(Rd, xZR, rex.w?(((-(lsb))%64)&0x3f):(((-(lsb))%32)&0x1f), (width)-1)
// Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
#define BFXILx(Rd, Rn, lsb, width) EMIT(BFM_gen(1, 0b01, 1, (lsb), (lsb)+(width)-1, Rn, Rd))
// Insert lsb:width part of Rn into low part of Rd (leaving rest of Rd untouched)
@@ -637,9 +651,9 @@
#define SBFMx(Rd, Rn, immr, imms) EMIT(SBFM_gen(1, 1, immr, imms, Rn, Rd))
#define SBFMw(Rd, Rn, immr, imms) EMIT(SBFM_gen(0, 0, immr, imms, Rn, Rd))
#define SBFMxw(Rd, Rn, immr, imms) EMIT(SBFM_gen(rex.w, rex.w, immr, imms, Rn, Rd))
-#define SBFXx(Rd, Rn, lsb, width) SBFMx(Rd, Rn, lsb, lsb+width-1)
-#define SBFXw(Rd, Rn, lsb, width) SBFMw(Rd, Rn, lsb, lsb+width-1)
-#define SBFXxw(Rd, Rn, lsb, width) SBFMxw(Rd, Rn, lsb, lsb+width-1)
+#define SBFXx(Rd, Rn, lsb, width) SBFMx(Rd, Rn, lsb, (lsb)+(width)-1)
+#define SBFXw(Rd, Rn, lsb, width) SBFMw(Rd, Rn, lsb, (lsb)+(width)-1)
+#define SBFXxw(Rd, Rn, lsb, width) SBFMxw(Rd, Rn, lsb, (lsb)+(width)-1)
#define SXTBx(Rd, Rn) SBFMx(Rd, Rn, 0, 7)
#define SXTBw(Rd, Rn) SBFMw(Rd, Rn, 0, 7)
#define SXTHx(Rd, Rn) SBFMx(Rd, Rn, 0, 15)
@@ -783,13 +797,13 @@
// imm16 must be 4-aligned
#define VLDR128_U12(Qt, Rn, imm16) EMIT(VMEM_gen(0b00, 0b11, ((uint32_t)((imm16)>>4))&0xfff, Rn, Qt))
// (imm14) must be 3-aligned
-#define VSTR32_U12(Dt, Rn, imm14) EMIT(VMEM_gen(0b10, 0b00, ((uint32_t)(imm14>>2))&0xfff, Rn, Dt))
+#define VSTR32_U12(Dt, Rn, imm14) EMIT(VMEM_gen(0b10, 0b00, ((uint32_t)((imm14)>>2))&0xfff, Rn, Dt))
// (imm15) must be 3-aligned
-#define VSTR64_U12(Dt, Rn, imm15) EMIT(VMEM_gen(0b11, 0b00, ((uint32_t)(imm15>>3))&0xfff, Rn, Dt))
+#define VSTR64_U12(Dt, Rn, imm15) EMIT(VMEM_gen(0b11, 0b00, ((uint32_t)((imm15)>>3))&0xfff, Rn, Dt))
// imm16 must be 4-aligned
#define VSTR128_U12(Qt, Rn, imm16) EMIT(VMEM_gen(0b00, 0b10, ((uint32_t)((imm16)>>4))&0xfff, Rn, Qt))
// (imm13) must be 1-aligned
-#define VSTR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b00, ((uint32_t)(imm13>>1))&0xfff, Rn, Ht))
+#define VSTR16_U12(Ht, Rn, imm13) EMIT(VMEM_gen(0b01, 0b00, ((uint32_t)((imm13)>>1))&0xfff, Rn, Ht))
#define VMEMUR_vector(size, opc, imm9, Rn, Rt) ((size)<<30 | 0b111<<27 | 1<<26 | (opc)<<22 | (imm9)<<12 | (Rn)<<5 | (Rt))
// signed offset, no alignement!
@@ -951,6 +965,15 @@
#define VSRI_16(Vd, Vn, shift) EMIT(VSRI_vector(0, 0b0010 | ((shift)>>3)&1, (shift)&7, Vn, Vd))
#define VSRI_32(Vd, Vn, shift) EMIT(VSRI_vector(0, 0b0100 | (((shift)>>3)&3), (shift)&7, Vn, Vd))
+// Reverse elements in 64-bit doublewords (vector). This instruction reverses the order of 8-bit, 16-bit, or 32-bit elements in each doubleword
+#define VREVx_vector(Q, U, size, o0, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | (o0)<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define VREV64_32(Vd, Vn) EMIT(VREVx_vector(0, 0, 0b10, 0, Vn, Vd))
+#define VREV64_16(Vd, Vn) EMIT(VREVx_vector(0, 0, 0b01, 0, Vn, Vd))
+#define VREV64_8(Vd, Vn) EMIT(VREVx_vector(0, 0, 0b00, 0, Vn, Vd))
+#define VREV64Q_32(Vd, Vn) EMIT(VREVx_vector(1, 0, 0b10, 0, Vn, Vd))
+#define VREV64Q_16(Vd, Vn) EMIT(VREVx_vector(1, 0, 0b01, 0, Vn, Vd))
+#define VREV64Q_8(Vd, Vn) EMIT(VREVx_vector(1, 0, 0b00, 0, Vn, Vd))
+
// Integer MATH
#define ADDSUB_vector(Q, U, size, Rm, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b10000<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define VADDQ_8(Vd, Vn, Vm) EMIT(ADDSUB_vector(1, 0, 0b00, Vm, Vn, Vd))
@@ -1094,6 +1117,12 @@
#define FADDP_vector(Q, sz, Rm, Rn, Rd) ((Q)<<30 | 1<<29 | 0b01110<<24 | (sz)<<22 | 1<<21 | (Rm)<<16 | 0b11010<<11 | 1<<10 | (Rn)<<5 | (Rd))
#define VFADDPQS(Vd, Vn, Vm) EMIT(FADDP_vector(1, 0, Vm, Vn, Vd))
#define VFADDPQD(Vd, Vn, Vm) EMIT(FADDP_vector(1, 1, Vm, Vn, Vd))
+#define VFADDPS(Vd, Vn, Vm) EMIT(FADDP_vector(0, 0, Vm, Vn, Vd))
+#define VFADDPD(Vd, Vn, Vm) EMIT(FADDP_vector(0, 1, Vm, Vn, Vd))
+
+#define FADDP_scalar(sz, Rn, Rd) (0b01<<30 | 1<<29 | 0b11110<<24 | (sz)<<22 | 0b11000<<17 | 0b01101<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define FADDPS(Sd, Sn) EMIT(FADDP_scalar(0, Sn, Sd))
+#define FADDPD(Dd, Dn) EMIT(FADDP_scalar(1, Dn, Dd))
// NEG / ABS
#define FNEGABS_scalar(type, opc, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (opc)<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
@@ -1360,22 +1389,12 @@
#define VFRINTRDQ(Vd,Vn, mode) EMIT(FRINT_vector(1, 0, (mode)&1, 1, ((mode)>>1)&1, Vn, Vd))
// round with mode, mode is 0 = TieEven, 1=+inf, 2=-inf, 3=zero
#define VFRINTRSQ(Vd,Vn, mode) EMIT(FRINT_vector(1, 0, (mode)&1, 0, ((mode)>>1)&1, Vn, Vd))
+#define VFRINTRS(Vd, Vn, mode) EMIT(FRINT_vector(0, 0, (mode)&1, 0, ((mode)>>1)&1, Vn, Vd))
#define FRINTI_scalar(type, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b001<<18 | 0b111<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
#define FRINTIS(Sd, Sn) EMIT(FRINTI_scalar(0b00, Sn, Sd))
#define FRINTID(Dd, Dn) EMIT(FRINTI_scalar(0b01, Dn, Dd))
-
-#define FRINTxx_scalar(type, op, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b0100<<17 | (op)<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
-#define FRINT32ZS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b00, Sn, Sd))
-#define FRINT32ZD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b00, Dn, Dd))
-#define FRINT32XS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b01, Sn, Sd))
-#define FRINT32XD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b01, Dn, Dd))
-#define FRINT64ZS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b10, Sn, Sd))
-#define FRINT64ZD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b10, Dn, Dd))
-#define FRINT64XS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b11, Sn, Sd))
-#define FRINT64XD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b11, Dn, Dd))
-
#define FRINT_scalar(type, rmode, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b001<<18 | (rmode)<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
// round toward 0 (truncate)
#define FRINTZS(Sd, Sn) EMIT(FRINT_scalar(0b00, 0b011, Sn, Sd))
@@ -1490,7 +1509,6 @@
#define VTRNQ1_32(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b10, Vm, 0, Vn, Vd))
#define VTRNQ1_16(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b01, Vm, 0, Vn, Vd))
#define VTRNQ1_8(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b00, Vm, 0, Vn, Vd))
-#define VSWP(Vd, Vn) VTRNQ1_64(Vd, Vn, Vn)
#define VTRNQ2_64(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b11, Vm, 1, Vn, Vd))
#define VTRNQ2_32(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b10, Vm, 1, Vn, Vd))
#define VTRNQ2_16(Vd, Vn, Vm) EMIT(TRN_gen(1, 0b01, Vm, 1, Vn, Vd))
@@ -1599,6 +1617,15 @@
#define CMEQQ_0_16(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b01, Rn, Rd))
#define CMEQQ_0_32(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b10, Rn, Rd))
#define CMEQQ_0_64(Rd, Rn) EMIT(CMEQ_0_vector(1, 0b11, Rn, Rd))
+// Greater Than 0
+#define CMCond_0_vector(Q, U, size, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b0100<<13 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define CMGT_0_8(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b00, 0, Rn, Rd))
+#define CMGT_0_16(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b01, 0, Rn, Rd))
+#define CMGT_0_32(Rd, Rn) EMIT(CMCond_0_vector(0, 0, 0b10, 0, Rn, Rd))
+#define CMGTQ_0_8(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b00, 0, Rn, Rd))
+#define CMGTQ_0_16(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b01, 0, Rn, Rd))
+#define CMGTQ_0_32(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b10, 0, Rn, Rd))
+#define CMGTQ_0_64(Rd, Rn) EMIT(CMCond_0_vector(1, 0, 0b11, 0, Rn, Rd))
// Vector Float CMP
// EQual
@@ -1757,9 +1784,11 @@
// MOV Immediate
#define MOVI_vector(Q, op, abc, cmode, defgh, Rd) ((Q)<<30 | (op)<<29 | 0b0111100000<<19 | (abc)<<16 | (cmode)<<12 | 1<<10 | (defgh)<<5 | (Rd))
#define MOVIQ_8(Rd, imm8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
+#define MOVIQ_16(Rd, imm8, lsl8) EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b1000|((lsl8)?0b10:0), ((imm8)&0b11111), Rd))
#define MOVI_8(Rd, imm8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
-#define MOVI_16(Rd, imm8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1000, ((imm8)&0b11111), Rd))
+#define MOVI_16(Rd, imm8, lsl8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1000|((lsl8)?0b10:0), ((imm8)&0b11111), Rd))
#define MOVI_32(Rd, imm8) EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b0000, ((imm8)&0b11111), Rd))
+#define MOVI_64(Rd, imm8) EMIT(MOVI_vector(0, 1, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
// SHLL and eXtend Long
#define SHLL_vector(Q, U, immh, immb, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b011110<<23 | (immh)<<19 | (immb)<<16 | 0b10100<<11 | 1<<10 | (Rn)<<5 | (Rd))
@@ -1919,4 +1948,272 @@
#define PMULL_128(Rd, Rn, Rm) EMIT(PMULL_gen(0, 0b11, Rm, Rn, Rd))
#define PMULL2_128(Rd, Rn, Rm) EMIT(PMULL_gen(1, 0b11, Rm, Rn, Rd))
+// ATOMIC extension
+#define ATOMIC_gen(size, A, R, Rs, opc, Rn, Rt) ((size)<<30 | 0b111<<27 | (A)<<23 | (R)<<22 | 1<<21 | (Rs)<<16 | (opc)<<12 | (Rn)<<5 | (Rt))
+// Atomic ADD
+#define LDADDxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b000, Rn, Rt))
+#define LDADDAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b000, Rn, Rt))
+#define LDADDALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b000, Rn, Rt))
+#define LDADDLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b000, Rn, Rt))
+#define STADDxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b000, Rn, 0b11111))
+#define STADDLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b000, Rn, 0b11111))
+#define LDADDB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b000, Rn, Rt))
+#define LDADDAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b000, Rn, Rt))
+#define LDADDALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b000, Rn, Rt))
+#define LDADDLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b000, Rn, Rt))
+#define STADDB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b000, Rn, 0b11111))
+#define STADDLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b000, Rn, 0b11111))
+#define LDADDH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b000, Rn, Rt))
+#define LDADDAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b000, Rn, Rt))
+#define LDADDALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b000, Rn, Rt))
+#define LDADDLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b000, Rn, Rt))
+#define STADDH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b000, Rn, 0b11111))
+#define STADDLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b000, Rn, 0b11111))
+// Atomic AND with complement (i.e. BIC)
+#define LDCLRxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b001, Rn, Rt))
+#define LDCLRLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b001, Rn, Rt))
+#define STCLRxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b001, Rn, 0b11111))
+#define STCLRLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b001, Rn, 0b11111))
+#define LDCLRB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b001, Rn, Rt))
+#define LDCLRLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b001, Rn, Rt))
+#define STCLRB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b001, Rn, 0b11111))
+#define STCLRLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b001, Rn, 0b11111))
+#define LDCLRH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b001, Rn, Rt))
+#define LDCLRALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b001, Rn, Rt))
+#define LDCLRLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b001, Rn, Rt))
+#define STCLRH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b001, Rn, 0b11111))
+#define STCLRLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b001, Rn, 0b11111))
+// Atomic EOR
+#define LDEORxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b010, Rn, Rt))
+#define LDEORAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b010, Rn, Rt))
+#define LDEORALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b010, Rn, Rt))
+#define LDEORLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b010, Rn, Rt))
+#define STEORxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b010, Rn, 0b11111))
+#define STEORLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b010, Rn, 0b11111))
+#define LDEORB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b010, Rn, Rt))
+#define LDEORAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b010, Rn, Rt))
+#define LDEORALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b010, Rn, Rt))
+#define LDEORLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b010, Rn, Rt))
+#define STEORB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b010, Rn, 0b11111))
+#define STEORLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b010, Rn, 0b11111))
+#define LDEORH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b010, Rn, Rt))
+#define LDEORAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b010, Rn, Rt))
+#define LDEORALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b010, Rn, Rt))
+#define LDEORLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b010, Rn, Rt))
+#define STEORH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b010, Rn, 0b11111))
+#define STEORLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b010, Rn, 0b11111))
+// Atomic OR
+#define LDSETxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b011, Rn, Rt))
+#define LDSETAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b011, Rn, Rt))
+#define LDSETALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b011, Rn, Rt))
+#define LDSETLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b011, Rn, Rt))
+#define STSETxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b011, Rn, 0b11111))
+#define STSETLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b011, Rn, 0b11111))
+#define LDSETB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b011, Rn, Rt))
+#define LDSETAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b011, Rn, Rt))
+#define LDSETALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b011, Rn, Rt))
+#define LDSETLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b011, Rn, Rt))
+#define STSETB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b011, Rn, 0b11111))
+#define STSETLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b011, Rn, 0b11111))
+#define LDSETH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b011, Rn, Rt))
+#define LDSETAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b011, Rn, Rt))
+#define LDSETALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b011, Rn, Rt))
+#define LDSETLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b011, Rn, Rt))
+#define STSETH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b011, Rn, 0b11111))
+#define STSETLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b011, Rn, 0b11111))
+// Atomic Signel Max
+#define LDSMAXxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b100, Rn, Rt))
+#define LDSMAXLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b100, Rn, Rt))
+#define STSMAXxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b100, Rn, 0b11111))
+#define STSMAXLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b100, Rn, 0b11111))
+#define LDSMAXB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b100, Rn, Rt))
+#define LDSMAXLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b100, Rn, Rt))
+#define STSMAXB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b100, Rn, 0b11111))
+#define STSMAXLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b100, Rn, 0b11111))
+#define LDSMAXH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b100, Rn, Rt))
+#define LDSMAXALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b100, Rn, Rt))
+#define LDSMAXLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b100, Rn, Rt))
+#define STSMAXH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b100, Rn, 0b11111))
+#define STSMAXLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b100, Rn, 0b11111))
+// Atomic Signed Min
+#define LDSMINxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b101, Rn, Rt))
+#define LDSMINLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b101, Rn, Rt))
+#define STSMINxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b101, Rn, 0b11111))
+#define STSMINLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b101, Rn, 0b11111))
+#define LDSMINB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b101, Rn, Rt))
+#define LDSMINLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b101, Rn, Rt))
+#define STSMINB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b101, Rn, 0b11111))
+#define STSMINLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b101, Rn, 0b11111))
+#define LDSMINH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b101, Rn, Rt))
+#define LDSMINALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b101, Rn, Rt))
+#define LDSMINLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b101, Rn, Rt))
+#define STSMINH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b101, Rn, 0b11111))
+#define STSMINLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b101, Rn, 0b11111))
+// Atomic Unsigned Max
+#define LDUMAXxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b110, Rn, Rt))
+#define LDUMAXLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b110, Rn, Rt))
+#define STUMAXxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b110, Rn, 0b11111))
+#define STUMAXLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b110, Rn, 0b11111))
+#define LDUMAXB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b110, Rn, Rt))
+#define LDUMAXLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b110, Rn, Rt))
+#define STUMAXB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b110, Rn, 0b11111))
+#define STUMAXLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b110, Rn, 0b11111))
+#define LDUMAXH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b110, Rn, Rt))
+#define LDUMAXALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b110, Rn, Rt))
+#define LDUMAXLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b110, Rn, Rt))
+#define STUMAXH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b110, Rn, 0b11111))
+#define STUMAXLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b110, Rn, 0b11111))
+// Atomic Unsigned Min
+#define LDUMINxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINAxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINALxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 1, 1, Rs, 0b111, Rn, Rt))
+#define LDUMINLxw(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b111, Rn, Rt))
+#define STUMINxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b111, Rn, 0b11111))
+#define STUMINLxw(Rs, Rn) EMIT(ATOMIC_gen(0b10+rex.w, 0, 1, Rs, 0b111, Rn, 0b11111))
+#define LDUMINB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINAB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINALB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 1, 1, Rs, 0b111, Rn, Rt))
+#define LDUMINLB(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b111, Rn, Rt))
+#define STUMINB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 0, Rs, 0b111, Rn, 0b11111))
+#define STUMINLB(Rs, Rn) EMIT(ATOMIC_gen(0b00, 0, 1, Rs, 0b111, Rn, 0b11111))
+#define LDUMINH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINAH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 0, Rs, 0b111, Rn, Rt))
+#define LDUMINALH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 1, 1, Rs, 0b111, Rn, Rt))
+#define LDUMINLH(Rs, Rt, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b111, Rn, Rt))
+#define STUMINH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b111, Rn, 0b11111))
+#define STUMINLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b111, Rn, 0b11111))
+
+// SWAPxx(Xs, Xt, Xn) : [Xn] => Xt, Xs => [Xn]
+#define SWAP_gen(size, A, R, Rs, Rn, Rt) ((size)<<30 | 0b111<<27 | (A)<<23 | (R)<<22 | 1<<21 | (Rs)<<16 | 1<<15 | (Rn)<<5 | (Rt))
+#define SWPxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 0, 0, Rs, Rn, Rt))
+#define SWPAxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 1, 0, Rs, Rn, Rt))
+#define SWPALxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 1, 1, Rs, Rn, Rt))
+#define SWPLxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 0, 1, Rs, Rn, Rt))
+#define SWPB(Rs, Rt, Rn) EMIT(SWAP_gen(0b00, 0, 0, Rs, Rn, Rt))
+#define SWPAB(Rs, Rt, Rn) EMIT(SWAP_gen(0b00, 1, 0, Rs, Rn, Rt))
+#define SWPALB(Rs, Rt, Rn) EMIT(SWAP_gen(0b00, 1, 1, Rs, Rn, Rt))
+#define SWPLB(Rs, Rt, Rn) EMIT(SWAP_gen(0b00, 0, 1, Rs, Rn, Rt))
+#define SWPH(Rs, Rt, Rn) EMIT(SWAP_gen(0b01, 0, 0, Rs, Rn, Rt))
+#define SWPAH(Rs, Rt, Rn) EMIT(SWAP_gen(0b01, 1, 0, Rs, Rn, Rt))
+#define SWPALH(Rs, Rt, Rn) EMIT(SWAP_gen(0b01, 1, 1, Rs, Rn, Rt))
+#define SWPLH(Rs, Rt, Rn) EMIT(SWAP_gen(0b01, 0, 1, Rs, Rn, Rt))
+
+#define CAS_gen(size, L, Rs, O0, Rn, Rt) ((size)<<30 | 0b001000<<24 | 1<<23 | (L)<<22 | 1<<21 | (Rs)<<16 | (O0)<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
+// Compare and Swap compare Rs with [Rn], write Rt is same, return old [Rn] in Rs
+#define CASxw(Rs, Rt, Rn) EMIT(CAS_gen(0b10+rex.w, 0, Rs, 0, Rn, Rt))
+#define CASAxw(Rs, Rt, Rn) EMIT(CAS_gen(0b10+rex.w, 1, Rs, 0, Rn, Rt))
+#define CASALxw(Rs, Rt, Rn) EMIT(CAS_gen(0b10+rex.w, 1, Rs, 1, Rn, Rt))
+#define CASLxw(Rs, Rt, Rn) EMIT(CAS_gen(0b10+rex.w, 0, Rs, 1, Rn, Rt))
+#define CASB(Rs, Rt, Rn) EMIT(CAS_gen(0b00, 0, Rs, 0, Rn, Rt))
+#define CASAB(Rs, Rt, Rn) EMIT(CAS_gen(0b00, 1, Rs, 0, Rn, Rt))
+#define CASALB(Rs, Rt, Rn) EMIT(CAS_gen(0b00, 1, Rs, 1, Rn, Rt))
+#define CASLB(Rs, Rt, Rn) EMIT(CAS_gen(0b00, 0, Rs, 1, Rn, Rt))
+#define CASH(Rs, Rt, Rn) EMIT(CAS_gen(0b01, 0, Rs, 0, Rn, Rt))
+#define CASAH(Rs, Rt, Rn) EMIT(CAS_gen(0b01, 1, Rs, 0, Rn, Rt))
+#define CASALH(Rs, Rt, Rn) EMIT(CAS_gen(0b01, 1, Rs, 1, Rn, Rt))
+#define CASLH(Rs, Rt, Rn) EMIT(CAS_gen(0b01, 0, Rs, 1, Rn, Rt))
+
+#define CASP_gen(size, L, Rs, O0, Rn, Rt) ((size)<<30 | 0b001000<<24 | 0<<23 | (L)<<22 | 1<<21 | (Rs)<<16 | (O0)<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
+// Compare and Swap with pair, Rs, Rs+1 and Rt,Rt+1 with [Rt]
+#define CASPxw(Rs, Rt, Rn) EMIT(CASP_gen(0b00+rex.w, 0, Rs, 0, Rn, Rt))
+#define CASPAxw(Rs, Rt, Rn) EMIT(CASP_gen(0b00+rex.w, 1, Rs, 0, Rn, Rt))
+#define CASPALxw(Rs, Rt, Rn) EMIT(CASP_gen(0b00+rex.w, 1, Rs, 1, Rn, Rt))
+#define CASPLxw(Rs, Rt, Rn) EMIT(CASP_gen(0b00+rex.w, 0, Rs, 1, Rn, Rt))
+
+// FLAGM extension
+// Invert Carry Flag
+#define CFINV() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b000<<5 | 0b11111)
+
+#define RMIF_gen(imm6, Rn, mask) (0b10111010000<<21 | (imm6)<<15 | 0b00001<<10 | (Rn)<<5 | (mask))
+// Rotate right reg and use as NZCV
+#define RMIF(Xn, shift, mask) EMIT(RMIF_gen(shift, Xn, mask))
+
+#define SETF_gen(sz, Rn) (0b00111010000<<21 | (sz)<<14 | 0b0010<<10 | (Rn)<<5 | 0b1101)
+// Set NZVc with 8bit value of reg: N=bit7, Z=[0..7]==0, V=bit8 eor bit7, C unchanged
+#define SETF8(Wn) EMIT(SETF_gen(0, Wn))
+// Set NZVc with 16bit value of reg: N=bit15, Z=[0..15]==0, V=bit16 eor bit15, C unchanged
+#define SETF16(Wn) EMIT(SETF_gen(1, Wn))
+
+// FLAGM2 extension
+// NZCV -> N=0 Z=C|V C=C&!V V=0
+#define AXFLAG() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b010<<5 | 0b11111)
+// NZCV -> N=!C&!Z Z=Z&C C=C|Z V=!C&Z
+#define XAFLAG() EMIT(0b1101010100<<22 | 0b0100<<12 | 0b001<<5 | 0b11111)
+
+// FRINTTS extension
+#define FRINTxx_scalar(type, op, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | 0b0100<<17 | (op)<<15 | 0b10000<<10 | (Rn)<<5 | (Rd))
+#define FRINT32ZS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b00, Sn, Sd))
+#define FRINT32ZD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b00, Dn, Dd))
+#define FRINT32XS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b01, Sn, Sd))
+#define FRINT32XD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b01, Dn, Dd))
+#define FRINT64ZS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b10, Sn, Sd))
+#define FRINT64ZD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b10, Dn, Dd))
+#define FRINT64XS(Sd, Sn) EMIT(FRINTxx_scalar(0b00, 0b11, Sn, Sd))
+#define FRINT64XD(Dd, Dn) EMIT(FRINTxx_scalar(0b01, 0b11, Dn, Dd))
+
+// CRC32 extension
+#define CRC32C_gen(sf, Rm, sz, Rn, Rd) ((sf)<<31 | 0b11010110<<21 | (Rm)<<16 | 0b010<<13 | 1<<12 | (sz)<<10 | (Rn)<<5 | (Rd))
+#define CRC32CB(Wd, Wn, Wm) EMIT(CRC32C_gen(0, Wm, 0b00, Wn, Wd))
+#define CRC32CH(Wd, Wn, Wm) EMIT(CRC32C_gen(0, Wm, 0b01, Wn, Wd))
+#define CRC32CW(Wd, Wn, Wm) EMIT(CRC32C_gen(0, Wm, 0b10, Wn, Wd))
+#define CRC32CX(Wd, Wn, Xm) EMIT(CRC32C_gen(1, Xm, 0b11, Wn, Wd))
+#define CRC32Cxw(Wd, Wn, Rm) EMIT(CRC32C_gen(rex.w, Rm, 0b10|rex.w, Wn, Wd))
+
+// SHA1 extension
+#define SHA1H_gen(Rn, Rd) (0b01011110<<24 | 0b10100<<17 | 0b10<<10 | (Rn)<<5 | (Rd))
+// SHA1 fixed rotate (ROL 30 of 32bits value)
+#define SHA1H(Sd, Sn) EMIT(SHA1H_gen(Sn, Sd))
+
+#define SHA1SU1_gen(Rn, Rd) (0b01011110<<24 | 0b10100<<17 | 0b00001<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+// SHA1 schedule update 1
+#define SHA1SU1(Vd, Vn) EMIT(SHA1SU1_gen(Vn, Vd))
+
+#define SHA1C_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | (Rn)<<5 | (Rd))
+// SHA1 hash update (choose)
+#define SHA1C(Qd, Sn, Vm) EMIT(SHA1C_gen(Vm, Sn, Qd))
+
+#define SHA1M_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | 0b010<<12 | (Rn)<<5 | (Rd))
+// SHA1 hash update (majority)
+#define SHA1M(Qd, Sn, Vm) EMIT(SHA1M_gen(Vm, Sn, Qd))
+
+#define SHA1P_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | 0b001<<12 | (Rn)<<5 | (Rd))
+// SHA1 hash update (parity)
+#define SHA1P(Qd, Sn, Vm) EMIT(SHA1P_gen(Vm, Sn, Qd))
+
+#define SHA256SU0_gen(Rn,Rd) (0b01011110<<24 | 0b10100<<17 | 0b00010<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+//SHA256 schedule update 0
+#define SHA256SU0(Vd, Vn) EMIT(SHA256SU0_gen(Vn, Vd))
+
+#define SHA256SU1_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | 0b110<<12 | (Rn)<<5 | (Rd))
+//SHA256 schedule update 1
+#define SHA256SU1(Vd, Vn, Vm) EMIT(SHA256SU1_gen(Vm, Vn, Vd))
+
+#define SHA256H_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | 0b100<<12 | (Rn)<<5 | (Rd))
+//SHA256 hash update (part 1)
+#define SHA256H(Vd, Vn, Vm) EMIT(SHA256H_gen(Vm, Vn, Vd))
+
+#define SHA256H2_gen(Rm, Rn, Rd) (0b01011110<<24 | (Rm)<<16 | 0b101<<12 | (Rn)<<5 | (Rd))
+//SHA256 hash update (part 2)
+#define SHA256H2(Vd, Vn, Vm) EMIT(SHA256H2_gen(Vm, Vn, Vd))
+
#endif //__ARM64_EMITTER_H__
diff --git a/src/dynarec/arm64/arm64_lock.S b/src/dynarec/arm64/arm64_lock.S
index b091101..e57137e 100644
--- a/src/dynarec/arm64/arm64_lock.S
+++ b/src/dynarec/arm64/arm64_lock.S
@@ -29,6 +29,10 @@
.global arm64_lock_incif0
.global arm64_lock_decifnot0
.global arm64_lock_store
+.global arm64_lock_store_dd
+.global arm64_lock_get_b
+.global arm64_lock_get_d
+.global arm64_lock_get_dd
arm64_lock_read_b:
dmb ish
@@ -254,3 +258,20 @@ arm64_lock_store:
str w1, [x0]
dmb ish
ret
+
+arm64_lock_store_dd:
+ str x1, [x0]
+ dmb ish
+ ret
+
+arm64_lock_get_b:
+ ldaxrb w0, [x0]
+ ret
+
+arm64_lock_get_d:
+ ldaxr w0, [x0]
+ ret
+
+arm64_lock_get_dd:
+ ldaxr x0, [x0]
+ ret
diff --git a/src/dynarec/arm64/arm64_lock.h b/src/dynarec/arm64/arm64_lock.h
index 118c807..1c827d0 100644
--- a/src/dynarec/arm64/arm64_lock.h
+++ b/src/dynarec/arm64/arm64_lock.h
@@ -69,4 +69,16 @@ extern int arm64_lock_decifnot0(void*p);
// atomic store (with memory barrier)
extern void arm64_lock_store(void*p, uint32_t v);
+// atomic store (with memory barrier)
+extern void arm64_lock_store_dd(void*p, uint64_t v);
+
+// atomic get (with memory barrier)
+extern uint8_t arm64_lock_get_b(void*p);
+
+// atomic get (with memory barrier)
+extern uint32_t arm64_lock_get_d(void*p);
+
+// atomic get (with memory barrier)
+extern void* arm64_lock_get_dd(void*p);
+
#endif //__ARM64_LOCK__H__
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 2806497..572d645 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -16,7 +16,7 @@ static const char* conds[] = {"cEQ", "cNE", "cCS", "cCC", "cMI", "cPL", "cVS", "
#define abs(A) (((A)<0)?(-(A)):(A))
typedef struct arm64_print_s {
- int N, S, U, L, Q;
+ int N, S, U, L, Q, A, R;
int t, n, m, d, t2, a;
int f, c, o, h, p;
int i, r, s;
@@ -60,6 +60,8 @@ int isMask(uint32_t opcode, const char* mask, arm64_print_t *a)
case 'N': a->N = (a->N<<1) | v; break;
case 'S': a->S = (a->S<<1) | v; break;
case 'U': a->U = (a->U<<1) | v; break;
+ case 'A': a->A = (a->A<<1) | v; break;
+ case 'R': a->R = (a->R<<1) | v; break;
case 'L': a->L = (a->L<<1) | v; break;
case 'Q': a->Q = (a->Q<<1) | v; break;
case 't': a->t = (a->t<<1) | v; break;
@@ -182,22 +184,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
if(isMask(opcode, "01111000010iiiiiiiii00nnnnnttttt", &a)) {
int offset = signExtend(imm, 9);
- snprintf(buff, sizeof(buff), "LDRUH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
+ snprintf(buff, sizeof(buff), "LDURH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
if(isMask(opcode, "001110001x0iiiiiiiii00nnnnnttttt", &a)) {
int offset = signExtend(imm, 9);
- snprintf(buff, sizeof(buff), "LDRUSB %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
+ snprintf(buff, sizeof(buff), "LDURSB %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
if(isMask(opcode, "011110001x0iiiiiiiii00nnnnnttttt", &a)) {
int offset = signExtend(imm, 9);
- snprintf(buff, sizeof(buff), "LDRUSH %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
+ snprintf(buff, sizeof(buff), "LDURSH %s, [%s, %s0x%x]", a.x?Xt[Rt]:Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
if(isMask(opcode, "10111000100iiiiiiiii00nnnnnttttt", &a)) {
int offset = signExtend(imm, 9);
- snprintf(buff, sizeof(buff), "LDRUSW %s, [%s, %s0x%x]", Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
+ snprintf(buff, sizeof(buff), "LDURSW %s, [%s, %s0x%x]", Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
if(isMask(opcode, "1x111000000iiiiiiiii00nnnnnttttt", &a)) {
@@ -213,7 +215,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
}
if(isMask(opcode, "01111000000iiiiiiiii00nnnnnttttt", &a)) {
int offset = signExtend(imm, 9);
- snprintf(buff, sizeof(buff), "STRUH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
+ snprintf(buff, sizeof(buff), "STURH %s, [%s, %s0x%x]", Wt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset));
return buff;
}
if(isMask(opcode, "1x11100101iiiiiiiiiiiinnnnnttttt", &a)) {
@@ -795,6 +797,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "CSEL %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]);
return buff;
}
+ if(isMask(opcode, "f1111010010mmmmmcccc00nnnnn0iiii", &a)) {
+ snprintf(buff, sizeof(buff), "CCMP %s, %s, %s 0x%x", sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond], imm);
+ return buff;
+ }
+
// MISC Bits
if(isMask(opcode, "f10110101100000000010onnnnnddddd", &a)) {
snprintf(buff, sizeof(buff), "CL%c %s, %s", option?'S':'Z', sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn]);
@@ -950,6 +957,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "VCMEQ V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);
return buff;
}
+ // CMP zero
+ if(isMask(opcode, "0QU01110ff100000100o10nnnnnddddd", &a)) {
+ const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
+ const char* Z[] = {"GT", "GE", "EQ", "LE"};
+ const char* Vd = Y[((sf)<<1) | a.Q];
+ const char* Cond = Z[(a.o << 1 | a.U)];
+ snprintf(buff, sizeof(buff), "VCM%s V%d.%s, V%d.%s, #0", Cond, Rd, Vd, Rn, Vd);
+ return buff;
+ }
+ // CMPLT zero
+ if(isMask(opcode, "0Q001110ff100000101010nnnnnddddd", &a)) {
+ const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
+ const char* Vd = Y[((sf)<<1) | a.Q];
+ snprintf(buff, sizeof(buff), "VCMLT V%d.%s, V%d.%s, #0", Rd, Vd, Rn, Vd);
+ return buff;
+ }
// MIN/MAX
if(isMask(opcode, "0QU01110ff1mmmmm0110o1nnnnnddddd", &a)) {
const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
@@ -965,11 +988,21 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm);
return buff;
}
- // MOV immediate (not)shifted 16bits & 32bits
+ // MOV immediate notshifted 16bits & 32bits
if(isMask(opcode, "0Q00111100000iiif00001iiiiiddddd", &a)) {
const char* Y[] = {"2S", "4S", "4H", "8H"};
const char* Vd = Y[(sf<<1)| a.Q];
- snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm);
+ int sh = 0;
+
+ snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm<<sh);
+ return buff;
+ }
+ // MOV immediate shifted 16bits
+ if(isMask(opcode, "0Q00111100000iii101001iiiiiddddd", &a)) {
+ const char* Y[] = {"4H", "8H"};
+ const char* Vd = Y[a.Q];
+
+ snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm<<8);
return buff;
}
@@ -1034,7 +1067,30 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
if(!offset)
snprintf(buff, sizeof(buff), "%s %c%d, [%s]", op?"STR":"LDR", s, Rt, XtSp[Rn]);
else
- snprintf(buff, sizeof(buff), "%s %c%d, [%s, %d]", op?"STR":"LDR", s, Rt, XtSp[Rn], offset);
+ snprintf(buff, sizeof(buff), "%s %c%d, [%s, 0x%x]", op?"STR":"LDR", s, Rt, XtSp[Rn], offset);
+ return buff;
+ }
+ if(isMask(opcode, "ss111100cc1mmmmmoooS10nnnnnttttt", &a)) {
+ char s = '?';
+ int size=imms;
+ int op=0;
+ if(size==0 && opc==1) {s='B';}
+ else if(size==1 && opc==1) {s='H';}
+ else if(size==2 && opc==1) {s='S';}
+ else if(size==3 && opc==1) {s='D';}
+ else if(size==0 && opc==3) {s='Q'; size = 4;}
+ else if(size==0 && opc==0) {s='B'; op=1;}
+ else if(size==1 && opc==0) {s='H'; op=1;}
+ else if(size==2 && opc==0) {s='S'; op=1;}
+ else if(size==3 && opc==0) {s='D'; op=1;}
+ else if(size==0 && opc==2) {s='Q'; op=1; size = 4;}
+
+ const char* extend[] = {"?0", "?1", "UXTW", "LSL", "?4", "?5", "SXTW", "SXTX"};
+ int amount = size*a.S;
+ if(option==3 && !amount)
+ snprintf(buff, sizeof(buff), "%s %c%d, [%s, %s]", op?"STR":"LDR", s, Rt, XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm]);
+ else
+ snprintf(buff, sizeof(buff), "%s %c%d, [%s, %s, %s %d]", op?"STR":"LDR", s, Rt, XtSp[Rn], ((option&1)==0)?Wt[Rm]:Xt[Rm], extend[option], amount);
return buff;
}
@@ -1094,6 +1150,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
return buff;
}
+ // FADDP
+ if(isMask(opcode, "0Q1011100f1mmmmm110101nnnnnddddd", &a)) {
+ char s = a.Q?'V':'D';
+ char d = sf?'D':'S';
+ int n = (a.Q && !sf)?4:2;
+ snprintf(buff, sizeof(buff), "VFADDP %c%d.%d%c, %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d, s, Rm, n, d);
+ return buff;
+ }
+ if(isMask(opcode, "011111100f110000110110nnnnnddddd", &a)) {
+ char s = (sf==0)?'S':((sf==1)?'D':'?');
+ snprintf(buff, sizeof(buff), "FADDP %c%d, %c%d, %c%d", s, Rd, s, Rn, s, Rm);
+ return buff;
+ }
+
// SQRT
if(isMask(opcode, "0Q1011101f100001111110nnnnnddddd", &a)) {
char s = a.Q?'V':'D';
@@ -1302,6 +1372,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "FCVT%sS %s, %c%d", roundings[a.c], sf?Xt[Rd]:Wt[Rd], s, Rn);
return buff;
}
+ if(isMask(opcode, "0QU01110of100001101o10nnnnnddddd", &a)) {
+ const char* Y[] = {"2S", "4S", "??", "2D"};
+ const char* Z[] = {"S", "S", "??", "D"};
+ const char* Vd = Y[(sf<<1) | a.Q];
+ const char* roundings[] = {"N", "M", "P", "Z"};
+ snprintf(buff, sizeof(buff), "VFCVT%s%s%s%s V%d.%s, V%d.%s", roundings[option], a.U?"U":"S", a.Q?"Q":"", Z[(sf<<1)|a.Q], Rd, Vd, Rn, Vd);
+ return buff;
+ }
// FMOV
if(isMask(opcode, "00011110pp100000010000nnnnnddddd", &a)) {
@@ -1548,7 +1626,139 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
snprintf(buff, sizeof(buff), "DMB %s", (Rn==0b1011)?"ISH":"???");
return buff;
}
+ // DSB ISH/ISHST
+ if(isMask(opcode, "11010101000000110011nnnn10011111", &a)) {
+ snprintf(buff, sizeof(buff), "DSB %s", (Rn==0b1011)?"ISH":((Rn==0b1010)?"ISHST":"???"));
+ return buff;
+ }
+ // CASxw
+ if(isMask(opcode, "1f0010001L1ssssso11111nnnnnttttt", &a)) {
+ snprintf(buff, sizeof(buff), "CAS%s%s %s, %s, [%s]", a.o?"A":"", a.L?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
+ return buff;
+ }
+ // CAS B/H
+ if(isMask(opcode, "0f0010001L1ssssso11111nnnnnttttt", &a)) {
+ snprintf(buff, sizeof(buff), "CAS%s%s%s %s, %s, [%s]", a.o?"A":"", a.L?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
+ return buff;
+ }
+ // CASPxw
+ if(isMask(opcode, "0f0010000L1ssssso11111nnnnnttttt", &a)) {
+ snprintf(buff, sizeof(buff), "CASP%s%s %s,%s, %s,%s, [%s]", a.o?"A":"", a.L?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rs+1]:Wt[Rs+1], sf?Xt[Rt]:Wt[Rt], sf?Xt[Rt+1]:Wt[Rt+1], XtSp[Rn]);
+ return buff;
+ }
+ // SWPxw
+ if(isMask(opcode, "1f111000AR1sssss100000nnnnnttttt", &a)) {
+ snprintf(buff, sizeof(buff), "SWP%s%s %s, %s, [%s]", a.A?"A":"", a.R?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
+ return buff;
+ }
+ // SWPxw
+ if(isMask(opcode, "0f111000AR1sssss100000nnnnnttttt", &a)) {
+ snprintf(buff, sizeof(buff), "CAS%s%s%s %s, %s, [%s]", a.A?"A":"", a.R?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
+ return buff;
+ }
+ // LDXXXxw
+ if(isMask(opcode, "1f111000AR1sssss0ooo00nnnnnttttt", &a)) {
+ const char* ops[] = { "ADD", "CLR", "EOR", "SET", "SMAX, SMIN", "UMAX", "UMIN" };
+ if((Rt == 0b11111) && !a.A) {
+ snprintf(buff, sizeof(buff), "ST%s%s %s, [%s]", ops[a.o], a.R?"L":"", sf?Xt[Rs]:Wt[Rs], XtSp[Rn]);
+ } else {
+ snprintf(buff, sizeof(buff), "LD%s%s%s %s, %s, [%s]", ops[a.o], a.A?"A":"", a.R?"L":"", sf?Xt[Rs]:Wt[Rs], sf?Xt[Rt]:Wt[Rt], XtSp[Rn]);
+ }
+ return buff;
+ }
+ // LDXXX B/H
+ if(isMask(opcode, "0f111000AR1sssss0ooo00nnnnnttttt", &a)) {
+ const char* ops[] = { "ADD", "CLR", "EOR", "SET", "SMAX, SMIN", "UMAX", "UMIN" };
+ if((Rt == 0b11111) && !a.A) {
+ snprintf(buff, sizeof(buff), "ST%s%s%s %s, [%s]", ops[a.o], a.R?"L":"", sf?"H":"B", Xt[Rs], XtSp[Rn]);
+ } else {
+ snprintf(buff, sizeof(buff), "LD%s%s%s%s %s, %s, [%s]", ops[a.o], a.A?"A":"", a.R?"L":"", sf?"H":"B", Xt[Rs], Xt[Rt], XtSp[Rn]);
+ }
+ return buff;
+ }
+ // AXFLAG
+ if(isMask(opcode, "11010101000000000100000001011111", &a)) {
+ snprintf(buff, sizeof(buff), "AXFLAG");
+ return buff;
+ }
+ // XAFLAG
+ if(isMask(opcode, "11010101000000000100000000111111", &a)) {
+ snprintf(buff, sizeof(buff), "XAFLAG");
+ return buff;
+ }
+ // CFINV
+ if(isMask(opcode, "11010101000000000100000000011111", &a)) {
+ snprintf(buff, sizeof(buff), "CFINV");
+ return buff;
+ }
+ // RMIF
+ if(isMask(opcode, "10111010000iiiiii00001nnnnn0oooo", &a)) {
+ snprintf(buff, sizeof(buff), "RMIF %s, #%d, #0x%x", Xt[Rn], imm, opc);
+ return buff;
+ }
+ // SETF
+ if(isMask(opcode, "00111010000000000f0010nnnnn01101", &a)) {
+ snprintf(buff, sizeof(buff), "SETF%d %s", 8<<sf, Xt[Rn]);
+ return buff;
+ }
+ // REV64
+ if(isMask(opcode, "0Q001110ff100000000010nnnnnddddd", &a)) {
+ const char* T[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "??"};
+ int sz = sf;
+ const char* Vn = T[(sz<<1)|a.Q];
+ const char* Vd = T[(sz<<1)|a.Q];
+ snprintf(buff, sizeof(buff), "REV64 V%d.%s, V%d.%s",Rd, Vd, Rn, Vn);
+ return buff;
+ }
+ //TRNx
+ if(isMask(opcode, "0Q001110ff0mmmmm0o1010nnnnnddddd", &a)) {
+ const char* T[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"};
+ int sz = sf;
+ const char* Vn = T[(sz<<1)|a.Q];
+ const char* Vm = T[(sz<<1)|a.Q];
+ const char* Vd = T[(sz<<1)|a.Q];
+ snprintf(buff, sizeof(buff), "TRN%d V%d.%s, V%d.%s, V%d.%s", a.o+1, Rd, Vd, Rn, Vn, Rm, Vm);
+ return buff;
+ }
+ //SHA1 stuffs
+ if(isMask(opcode, "0101111000101000000010nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA1H S%d, S%d", Rd, Rn);
+ return buff;
+ }
+ if(isMask(opcode, "0101111000101000000110nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA1SU1 V%d.4S, V%d.4S", Rd, Rn);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm000000nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA1C Q%d, S%d, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm001000nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA1M Q%d, S%d, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm000100nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA1P Q%d, S%d, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
+ //SHA256 stuffs
+ if(isMask(opcode, "0101111000101000001010nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA256SU0 V%d.4S, V%d.4S", Rd, Rn);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm011000nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA256SU1 V%d.4S, V%d.4S, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm010000nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA256H Q%d, Q%d, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
+ if(isMask(opcode, "01011110000mmmmm010100nnnnnddddd", &a)) {
+ snprintf(buff, sizeof(buff), "SHA256H2 Q%d, Q%d, V%d.4S", Rd, Rn, Rm);
+ return buff;
+ }
snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));
return buff;
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index c434dbd..697ff0d 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -726,7 +726,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
case 0x67:
- addr = dynarec64_67(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ if(rex.is32bits)
+ addr = dynarec64_67_32(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ else
+ addr = dynarec64_67(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
case 0x68:
INST_NAME("PUSH Id");
@@ -766,9 +769,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SMULL(gd, ed, x4);
UFLAG_RES(gd);
LSRx(x3, gd, 32);
+ MOVw_REG(gd, gd);
UFLAG_OP1(x3);
UFLAG_DF(x3, d_imul32);
- MOVw_REG(gd, gd);
} else {
MULxw(gd, ed, x4);
}
@@ -814,8 +817,21 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
+ case 0x6C:
case 0x6D:
- INST_NAME("INSD");
+ INST_NAME(opcode == 0x6C ? "INSB" : "INSD");
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ GETIP(ip);
+ STORE_XEMU_CALL(xRIP);
+ CALL(native_priv, -1);
+ LOAD_XEMU_CALL(xRIP);
+ jump_to_epilog(dyn, 0, xRIP, ninst);
+ *need_epilog = 0;
+ *ok = 0;
+ break;
+ case 0x6E:
+ case 0x6F:
+ INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD");
SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
STORE_XEMU_CALL(xRIP);
@@ -1036,8 +1052,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("(LOCK)XCHG Eb, Gb");
// Do the swap
nextop = F8;
+ GETGB(x4);
if(MODREG) {
- GETGB(x4);
if(rex.rex) {
ed = xRAX+(nextop&7)+(rex.b<<3);
eb1 = ed;
@@ -1045,25 +1061,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
ed = (nextop&7);
eb1 = xRAX+(ed&3);
- eb2 = ((ed&4)>>2);
+ eb2 = ((ed&4)<<1);
}
- UBFXw(x1, eb1, eb2*8, 8);
+ UBFXw(x1, eb1, eb2, 8);
// do the swap 14 -> ed, 1 -> gd
- BFIx(gb1, x1, gb2*8, 8);
- BFIx(eb1, x4, eb2*8, 8);
+ BFIx(eb1, x4, eb2, 8);
} else {
- SMDMB();
- GETGB(x4);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- // do the swap with exclusive locking
- LDAXRB(x1, ed);
- // do the swap 4 -> strb(ed), 1 -> gd
- STLXRB(x3, x4, ed);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ SWPALB(x4, x1, ed);
+ } else {
+ MARKLOCK;
+ // do the swap with exclusive locking
+ LDAXRB(x1, ed);
+ // do the swap 4 -> strb(ed), 1 -> gd
+ STLXRB(x3, x4, ed);
+ CBNZx_MARKLOCK(x3);
+ }
SMDMB();
- BFIx(gb1, x1, gb2*8, 8);
}
+ BFIx(gb1, x1, gb2, 8);
break;
case 0x87:
INST_NAME("(LOCK)XCHG Ed, Gd");
@@ -1077,20 +1094,39 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
GETGD;
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- SMDMB();
- TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE);
- MARKLOCK;
- LDAXRxw(x1, ed);
- STLXRxw(x3, gd, ed);
- CBNZx_MARKLOCK(x3);
- B_MARK2_nocond;
- MARK;
- LDRxw_U12(x1, ed, 0);
- STRxw_U12(gd, ed, 0);
- MARK2;
- SMDMB();
- MOVxw_REG(gd, x1);
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ SWPALxw(gd, gd, ed);
+ SMDMB();
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, ed);
+ STLXRxw(x3, gd, ed);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ if(!ALIGNED_ATOMICxw) {
+ B_MARK2_nocond;
+ }
+ }
+ if(!ALIGNED_ATOMICxw) {
+ MARK;
+ LDRxw_U12(x1, ed, 0);
+ LDAXRB(x3, ed);
+ STLXRB(x3, gd, ed);
+ CBNZx_MARK(x3);
+ STRxw_U12(gd, ed, 0);
+ SMDMB();
+ MARK2;
+ }
+ if(!ALIGNED_ATOMICxw || !arm64_atomics) {
+ MOVxw_REG(gd, x1);
+ }
}
break;
case 0x88:
@@ -1101,12 +1137,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
gb2 = 0;
gb1 = xRAX + gd;
} else {
- gb2 = ((gd&4)>>2);
+ gb2 = ((gd&4)<<1);
gb1 = xRAX+(gd&3);
}
if(gb2) {
gd = x4;
- UBFXw(gd, gb1, gb2*8, 8);
+ UBFXw(gd, gb1, gb2, 8);
} else {
gd = gb1; // no need to extract
}
@@ -1147,7 +1183,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
gd = (nextop&0x38)>>3;
gb1 = xRAX+(gd&3);
- gb2 = ((gd&4)>>2);
+ gb2 = ((gd&4)<<1);
}
if(MODREG) {
if(rex.rex) {
@@ -1170,7 +1206,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LDB(x4, wback, fixedaddress);
ed = x4;
}
- BFIx(gb1, ed, gb2*8, 8);
+ BFIx(gb1, ed, gb2, 8);
break;
case 0x8B:
INST_NAME("MOV Gd, Ed");
@@ -1191,7 +1227,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if((nextop&0xC0)==0xC0) { // reg <= seg
LDRw_U12(xRAX+(nextop&7)+(rex.b<<3), xEmu, offsetof(x64emu_t, segs[u8]));
} else { // mem <= seg
- LDRw_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
+ LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
STH(x3, wback, fixedaddress);
SMWRITE2();
@@ -1225,7 +1261,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LDH(x1, wback, fixedaddress);
ed = x1;
}
- STRw_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+ STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
break;
case 0x8F:
@@ -1296,10 +1332,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SET_DFNONE(x1);
if(box64_wine) { // should this be done all the time?
TBZ_NEXT(xFlags, F_TF);
- MOV64x(x1, addr);
- STORE_XEMU_CALL(x1);
- CALL(native_singlestep, -1);
- BFCw(xFlags, F_TF, 1);
+ // go to epilog, TF should trigger at end of next opcode, so using Interpretor only
+ jump_to_epilog(dyn, addr, 0, ninst);
}
break;
case 0x9E:
@@ -1324,7 +1358,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
- SMREAD();
+ if(isLockAddress(u64)) lock=1; else lock = 0;
+ SMREADLOCK(lock);
LDRB_U12(x2, x1, 0);
BFIx(xRAX, x2, 0, 8);
break;
@@ -1335,7 +1370,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
- SMREAD();
+ if(isLockAddress(u64)) lock=1; else lock = 0;
+ SMREADLOCK(lock);
LDRxw_U12(xRAX, x1, 0);
break;
case 0xA2:
@@ -1345,8 +1381,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
+ if(isLockAddress(u64)) lock=1; else lock = 0;
STRB_U12(xRAX, x1, 0);
- SMWRITE();
+ SMWRITELOCK(lock);
break;
case 0xA3:
INST_NAME("MOV Od,EAX");
@@ -1355,10 +1392,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
+ if(isLockAddress(u64)) lock=1; else lock = 0;
STRxw_U12(xRAX, x1, 0);
- SMWRITE();
+ SMWRITELOCK(lock);
break;
case 0xA4:
+ SMREAD();
if(rep) {
INST_NAME("REP MOVSB");
CBZx_NEXT(xRCX);
@@ -1383,8 +1422,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ADDx_REG(xRSI, xRSI, x3);
ADDx_REG(xRDI, xRDI, x3);
}
+ SMWRITE();
break;
case 0xA5:
+ SMREAD();
if(rep) {
INST_NAME("REP MOVSD");
CBZx_NEXT(xRCX);
@@ -1409,6 +1450,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ADDx_REG(xRSI, xRSI, x3);
ADDx_REG(xRDI, xRDI, x3);
}
+ SMWRITE();
break;
case 0xA6:
switch(rep) {
@@ -1524,6 +1566,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STRB_U12(xRAX, xRDI, 0);
ADDx_REG(xRDI, xRDI, x3);
}
+ SMWRITE();
break;
case 0xAB:
if(rep) {
@@ -1546,6 +1589,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STRxw_U12(xRAX, xRDI, 0);
ADDx_REG(xRDI, xRDI, x3);
}
+ SMWRITE();
break;
case 0xAC:
if(rep) {
@@ -1621,6 +1665,41 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
}
break;
+ case 0xAF:
+ switch(rep) {
+ case 1:
+ case 2:
+ if(rep==1) {INST_NAME("REPNZ SCASD");} else {INST_NAME("REPZ SCASD");}
+ MAYSETFLAGS();
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ CBZx_NEXT(xRCX);
+ TBNZ_MARK2(xFlags, F_DF);
+ MARK; // Part with DF==0
+ LDRxw_S9_postindex(x2, xRDI, rex.w?8:4);
+ SUBx_U12(xRCX, xRCX, 1);
+ CMPSxw_REG(xRAX, x2);
+ B_MARK3((rep==1)?cEQ:cNE);
+ CBNZx_MARK(xRCX);
+ B_MARK3_nocond;
+ MARK2; // Part with DF==1
+ LDRxw_S9_postindex(x2, xRDI, rex.w?-8:-4);
+ SUBx_U12(xRCX, xRCX, 1);
+ CMPSxw_REG(xRAX, x2);
+ B_MARK3((rep==1)?cEQ:cNE);
+ CBNZx_MARK2(xRCX);
+ MARK3; // end
+ emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5);
+ break;
+ default:
+ INST_NAME("SCASD");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ GETDIR(x3, rex.w?8:4);
+ LDRxw_U12(x2, xRDI, 0);
+ ADDx_REG(xRDI, xRDI, x3);
+ emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5);
+ break;
+ }
+ break;
case 0xB0:
@@ -1674,23 +1753,29 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Eb, Ib");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
- GETEB(x1, 1);
- u8 = F8;
- MOV32w(x2, u8);
- CALL_(rol8, ed, x3);
- EBBACK;
+ if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEB(x1, 1);
+ u8 = F8;
+ emit_rol8c(dyn, ninst, x1, u8&7, x4, x5);
+ EBBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 1:
INST_NAME("ROR Eb, Ib");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
- GETEB(x1, 1);
- u8 = F8;
- MOV32w(x2, u8);
- CALL_(ror8, ed, x3);
- EBBACK;
+ if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEB(x1, 1);
+ u8 = F8;
+ emit_ror8c(dyn, ninst, x1, u8&7, x4, x5);
+ EBBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 2:
INST_NAME("RCL Eb, Ib");
@@ -1717,60 +1802,44 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
case 6:
INST_NAME("SHL Eb, Ib");
- GETEB(x1, 1);
- u8 = (F8)&0x1f;
+ u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
- SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_IF{
- MOV32w(x4, u8); UFLAG_OP2(x4);
- };
- UFLAG_OP1(ed);
- LSLw(ed, ed, u8);
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETEB(x1, 1);
+ u8 = (F8)&0x1f;
+ emit_shl8c(dyn, ninst, ed, u8, x4, x5);
EBBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shl8);
} else {
- NOP;
+ FAKEED;
+ F8;
}
break;
case 5:
INST_NAME("SHR Eb, Ib");
- GETEB(x1, 1);
- u8 = (F8)&0x1f;
+ u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
- SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_IF{
- MOV32w(x4, u8); UFLAG_OP2(x4);
- };
- UFLAG_OP1(ed);
- if(u8) {
- LSRw(ed, ed, u8);
- EBBACK;
- }
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shr8);
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETEB(x1, 1);
+ u8 = (F8)&0x1f;
+ emit_shr8c(dyn, ninst, ed, u8, x4, x5);
+ EBBACK;
} else {
- NOP;
+ FAKEED;
+ F8;
}
break;
case 7:
INST_NAME("SAR Eb, Ib");
- GETSEB(x1, 1);
- u8 = (F8)&0x1f;
+ u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
- SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_IF{
- MOV32w(x4, u8); UFLAG_OP2(x4);
- };
- UFLAG_OP1(ed);
- if(u8) {
- ASRw(ed, ed, u8);
- EBBACK;
- }
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_sar8);
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETSEB(x1, 1);
+ u8 = (F8)&0x1f;
+ emit_sar8c(dyn, ninst, ed, u8, x4, x5);
+ EBBACK;
} else {
- NOP;
+ FAKEED;
+ F8;
}
break;
}
@@ -1780,19 +1849,31 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, Ib");
- SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
- GETED(1);
- u8 = (F8)&(rex.w?0x3f:0x1f);
- emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
- if(u8) { WBACK; }
+ u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+ if(u8) {
+ SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
+ GETED(1);
+ u8 = (F8)&(rex.w?0x3f:0x1f);
+ emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
+ WBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 1:
INST_NAME("ROR Ed, Ib");
- SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
- GETED(1);
- u8 = (F8)&(rex.w?0x3f:0x1f);
- emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
- if(u8) { WBACK; }
+ u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+ if(u8) {
+ SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
+ GETED(1);
+ u8 = (F8)&(rex.w?0x3f:0x1f);
+ emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
+ WBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 2:
INST_NAME("RCL Ed, Ib");
@@ -1819,27 +1900,45 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
case 6:
INST_NAME("SHL Ed, Ib");
- SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
- GETED(1);
- u8 = (F8)&(rex.w?0x3f:0x1f);
- emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
- WBACK;
+ u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+ if(u8) {
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETED(1);
+ u8 = (F8)&(rex.w?0x3f:0x1f);
+ emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
+ WBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 5:
INST_NAME("SHR Ed, Ib");
- SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
- GETED(1);
- u8 = (F8)&(rex.w?0x3f:0x1f);
- emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
- if(u8) { WBACK; }
+ u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+ if(u8) {
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETED(1);
+ u8 = (F8)&(rex.w?0x3f:0x1f);
+ emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+ WBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 7:
INST_NAME("SAR Ed, Ib");
- SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
- GETED(1);
- u8 = (F8)&(rex.w?0x3f:0x1f);
- emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
- if(u8) { WBACK; }
+ u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+ if(u8) {
+ SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
+ GETED(1);
+ u8 = (F8)&(rex.w?0x3f:0x1f);
+ emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
+ WBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
}
break;
@@ -1939,8 +2038,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
*need_epilog = 1;
} else {
MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
+ x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x3, x4, 0);
sse_purge07cache(dyn, ninst, x3);
+ SMEND();
tmp = isSimpleWrapper(*(wrapper_t*)(addr));
if(isRetX87Wrapper(*(wrapper_t*)(addr)))
// return value will be on the stack, so the stack depth needs to be updated
@@ -1970,13 +2071,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#if 1
INST_NAME("INT 3");
// check if TRAP signal is handled
- LDRx_U12(x1, xEmu, offsetof(x64emu_t, context));
+ TABLE64(x1, (uintptr_t)my_context);
MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP]));
LDRx_REG(x3, x1, x2);
+ //LDRx_U12(x3, x1, offsetof(box64context_t, signals[SIGTRAP]));
CMPSx_U12(x3, 0);
- B_NEXT(cNE);
- MOV32w(x1, SIGTRAP);
- CALL_(raise, -1, 0);
+ B_NEXT(cEQ);
+ GETIP(ip);
+ STORE_XEMU_CALL(xRIP);
+ CALL(native_int3, -1);
+ LOAD_XEMU_CALL(xRIP);
break;
#else
DEFAULT;
@@ -2015,7 +2119,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
STORE_XEMU_CALL(xRIP);
- CALL(native_priv, -1);
+ CALL(native_int, -1);
LOAD_XEMU_CALL(xRIP);
jump_to_epilog(dyn, 0, xRIP, ninst);
*need_epilog = 0;
@@ -2032,105 +2136,63 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
*ok = 0;
break;
case 0xD0:
- case 0xD2: // TODO: Jump if CL is 0
nextop = F8;
switch((nextop>>3)&7) {
case 0:
- if(opcode==0xD0) {
- INST_NAME("ROL Eb, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("ROL Eb, CL");
- ANDSw_mask(x2, xRCX, 0, 0b00100);
- }
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
+ INST_NAME("ROL Eb, 1");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETEB(x1, 0);
- CALL_(rol8, x1, x3);
+ emit_rol8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
break;
case 1:
- if(opcode==0xD0) {
- INST_NAME("ROR Eb, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("ROR Eb, CL");
- ANDSw_mask(x2, xRCX, 0, 0b00100);
- }
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
+ INST_NAME("ROR Eb, 1");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETEB(x1, 0);
- CALL_(ror8, x1, x3);
+ emit_ror8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
break;
case 2:
- if(opcode==0xD0) {INST_NAME("RCL Eb, 1");} else {INST_NAME("RCL Eb, CL");}
+ INST_NAME("RCL Eb, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
- if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}
+ MOV32w(x2, 1);
GETEB(x1, 0);
CALL_(rcl8, x1, x3);
EBBACK;
break;
case 3:
- if(opcode==0xD0) {INST_NAME("RCR Eb, 1");} else {INST_NAME("RCR Eb, CL");}
+ INST_NAME("RCR Eb, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
- if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}
+ MOV32w(x2, 1);
GETEB(x1, 0);
CALL_(rcr8, x1, x3);
EBBACK;
break;
case 4:
case 6:
- if(opcode==0xD0) {
- INST_NAME("SHL Eb, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("SHL Eb, CL");
- ANDSw_mask(x2, xRCX, 0, 0b00100);
- }
- SETFLAGS(X_ALL, SF_PENDING);
+ INST_NAME("SHL Eb, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEB(x1, 0);
- UFLAG_OP12(ed, x2)
- LSLw_REG(ed, ed, x2);
+ emit_shl8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shl8);
break;
case 5:
- if(opcode==0xD0) {
- INST_NAME("SHR Eb, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("SHR Eb, CL");
- ANDSw_mask(x2, xRCX, 0, 0b00100);
- }
- SETFLAGS(X_ALL, SF_PENDING);
+ INST_NAME("SHR Eb, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEB(x1, 0);
- UFLAG_OP12(ed, x2);
- LSRw_REG(ed, ed, x2);
+ emit_shr8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shr8);
break;
case 7:
- if(opcode==0xD0) {
- INST_NAME("SAR Eb, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("SAR Eb, CL");
- ANDSw_mask(x2, xRCX, 0, 0b00100);
- }
- SETFLAGS(X_ALL, SF_PENDING);
+ INST_NAME("SAR Eb, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETSEB(x1, 0);
- UFLAG_OP12(ed, x2)
- ASRw_REG(ed, ed, x2);
+ emit_sar8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_sar8);
break;
}
break;
@@ -2195,29 +2257,164 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
}
break;
+ case 0xD2: // TODO: Jump if CL is 0
+ nextop = F8;
+ switch((nextop>>3)&7) {
+ case 0:
+ INST_NAME("ROL Eb, CL");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ }
+ ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007
+ MOV32w(x4, 8);
+ SUBx_REG(x2, x4, x2);
+ GETEB(x1, 0);
+ ORRw_REG_LSL(ed, ed, ed, 8);
+ LSRw_REG(ed, ed, x2);
+ EBBACK;
+ UFLAG_IF { // calculate flags directly
+ CMPSw_U12(x2, 7);
+ B_MARK(cNE);
+ ADDxw_REG_LSR(x3, ed, ed, 7);
+ BFIw(xFlags, x3, F_OF, 1);
+ MARK;
+ BFIw(xFlags, ed, F_CF, 1);
+ UFLAG_DF(x2, d_none);
+ }
+ break;
+ case 1:
+ INST_NAME("ROR Eb, CL");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007
+ GETEB(x1, 0);
+ UFLAG_IF {
+ B_NEXT(cEQ);
+ }
+ ORRw_REG_LSL(ed, ed, ed, 8);
+ LSRw_REG(ed, ed, x2);
+ EBBACK;
+ UFLAG_IF { // calculate flags directly
+ CMPSw_U12(x2, 1);
+ B_MARK(cNE);
+ LSRxw(x2, ed, 6); // x2 = d>>30
+ EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
+ BFIw(xFlags, x2, F_OF, 1);
+ MARK;
+ BFXILw(xFlags, ed, 7, 1);
+ UFLAG_DF(x2, d_none);
+ }
+ break;
+ case 2:
+ INST_NAME("RCL Eb, CL");
+ MESSAGE(LOG_DUMP, "Need Optimization\n");
+ READFLAGS(X_CF);
+ SETFLAGS(X_OF|X_CF, SF_SET);
+ ANDSw_mask(x2, xRCX, 0, 0b00100);
+ GETEB(x1, 0);
+ CALL_(rcl8, x1, x3);
+ EBBACK;
+ break;
+ case 3:
+ INST_NAME("RCR Eb, CL");
+ MESSAGE(LOG_DUMP, "Need Optimization\n");
+ READFLAGS(X_CF);
+ SETFLAGS(X_OF|X_CF, SF_SET);
+ ANDSw_mask(x2, xRCX, 0, 0b00100);
+ GETEB(x1, 0);
+ CALL_(rcr8, x1, x3);
+ EBBACK;
+ break;
+ case 4:
+ case 6:
+ INST_NAME("SHL Eb, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ } else {
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ GETEB(x1, 0);
+ emit_shl8(dyn, ninst, x1, x2, x5, x4);
+ EBBACK;
+ break;
+ case 5:
+ INST_NAME("SHR Eb, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ } else {
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ GETEB(x1, 0);
+ emit_shr8(dyn, ninst, x1, x2, x5, x4);
+ EBBACK;
+ break;
+ case 7:
+ INST_NAME("SAR Eb, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ } else {
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ GETSEB(x1, 0);
+ emit_sar8(dyn, ninst, x1, x2, x5, x4);
+ EBBACK;
+ break;
+ }
+ break;
case 0xD3:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, CL");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
- if(rex.w) {
- ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
} else {
- ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
}
MOV64xw(x4, (rex.w?64:32));
SUBx_REG(x3, x4, x3);
GETED(0);
- if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
- B_NEXT(cEQ);
+ UFLAG_IF {
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ B_NEXT(cEQ);
+ }
RORxw_REG(ed, ed, x3);
WBACK;
UFLAG_IF { // calculate flags directly
CMPSw_U12(x3, rex.w?63:31);
B_MARK(cNE);
- LSRxw(x1, ed, rex.w?63:31);
- ADDxw_REG(x1, x1, ed);
+ ADDxw_REG_LSR(x1, ed, ed, rex.w?63:31);
BFIw(xFlags, x1, F_OF, 1);
MARK;
BFIw(xFlags, ed, F_CF, 1);
@@ -2227,14 +2424,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1:
INST_NAME("ROR Ed, CL");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
- if(rex.w) {
- ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
} else {
- ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
}
GETED(0);
- if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
- B_NEXT(cEQ);
+ UFLAG_IF {
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ B_NEXT(cEQ);
+ }
RORxw_REG(ed, ed, x3);
WBACK;
UFLAG_IF { // calculate flags directly
@@ -2244,8 +2453,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
BFIw(xFlags, x2, F_OF, 1);
MARK;
- LSRxw(x2, ed, rex.w?63:31);
- BFIw(xFlags, x2, F_CF, 1);
+ BFXILxw(xFlags, ed, rex.w?63:31, 1);
UFLAG_DF(x2, d_none);
}
break;
@@ -2254,6 +2462,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
if(rex.w) {
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
@@ -2270,6 +2480,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
if(rex.w) {
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
@@ -2285,42 +2497,78 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 6:
INST_NAME("SHL Ed, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
- if(rex.w) {
- ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
} else {
- ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
}
GETED(0);
- if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
- B_NEXT(cEQ);
+ UFLAG_IF {
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ B_NEXT(cEQ);
+ }
emit_shl32(dyn, ninst, rex, ed, x3, x5, x4);
WBACK;
break;
case 5:
INST_NAME("SHR Ed, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
- if(rex.w) {
- ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
} else {
- ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
}
GETED(0);
- if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
- B_NEXT(cEQ);
+ UFLAG_IF {
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ B_NEXT(cEQ);
+ }
emit_shr32(dyn, ninst, rex, ed, x3, x5, x4);
WBACK;
break;
case 7:
INST_NAME("SAR Ed, CL");
SETFLAGS(X_ALL, SF_PENDING);
- if(rex.w) {
- ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
} else {
- ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
}
GETED(0);
- if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
- B_NEXT(cEQ);
+ UFLAG_IF {
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ B_NEXT(cEQ);
+ }
UFLAG_OP12(ed, x3);
ASRxw_REG(ed, ed, x3);
WBACK;
@@ -2330,13 +2578,21 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
+ case 0xD7:
+ INST_NAME("XLAT");
+ UXTBw(x1, xRAX);
+ LDRB_REG(x1, xRBX, x1);
+ BFIx(xRAX, x1, 0, 8);
+ break;
case 0xD8:
addr = dynarec64_D8(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
case 0xD9:
addr = dynarec64_D9(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
-
+ case 0xDA:
+ addr = dynarec64_DA(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ break;
case 0xDB:
addr = dynarec64_DB(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
@@ -2422,7 +2678,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch(tmp) {
case 3:
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
- //BARRIER_NEXT(BARRIER_FULL);
if(dyn->last_ip && (addr-dyn->last_ip<0x1000)) {
ADDx_U12(x2, xRIP, addr-dyn->last_ip);
} else {
@@ -2432,6 +2687,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall-1)), dyn->insts[ninst].retn);
SKIPTEST(x1); // disable test as this hack dos 2 instructions for 1
// calling a native function
+ SMEND();
sse_purge07cache(dyn, ninst, x3);
if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall) {
tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2));
@@ -2477,9 +2733,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
}
// regular call
- //BARRIER_NEXT(1);
if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
BARRIER(BARRIER_FULL);
+ BARRIER_NEXT(BARRIER_FULL);
} else {
BARRIER(BARRIER_FLOAT);
*need_epilog = 0;
@@ -2492,12 +2748,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
PUSH1z(x2);
if(box64_dynarec_callret) {
+ SET_HASCALLRET();
// Push actual return address
if(addr < (dyn->start+dyn->isize)) {
// there is a next...
j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
ADR_S20(x4, j64);
+ MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
} else {
+ MESSAGE(LOG_NONE, "\tCALLRET set return to Jmptable(%p)\n", (void*)addr);
j64 = getJumpTableAddress64(addr);
TABLE64(x4, j64);
LDRx_U12(x4, x4, 0);
@@ -2597,44 +2856,50 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 3:
INST_NAME("NEG Eb");
SETFLAGS(X_ALL, SF_SET_PENDING);
- GETEB(x1, 0);
+ GETSEB(x1, 0);
emit_neg8(dyn, ninst, x1, x2, x4);
EBBACK;
break;
case 4:
INST_NAME("MUL AL, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x1, d_mul8);
GETEB(x1, 0);
UXTBw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIx(xRAX, x1, 0, 16);
+ UFLAG_DF(x1, d_mul8);
break;
case 5:
INST_NAME("IMUL AL, Eb");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x1, d_imul8);
GETSEB(x1, 0);
SXTBw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIx(xRAX, x1, 0, 16);
+ UFLAG_DF(x1, d_imul8);
break;
case 6:
INST_NAME("DIV Eb");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
SETFLAGS(X_ALL, SF_SET);
GETEB(x1, 0);
- CALL(div8, -1);
+ UXTHw(x2, xRAX);
+ UDIVw(x3, x2, ed);
+ MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
+ BFIx(xRAX, x3, 0, 8);
+ BFIx(xRAX, x4, 8, 8);
break;
case 7:
INST_NAME("IDIV Eb");
SKIPTEST(x1);
- MESSAGE(LOG_DUMP, "Need Optimization\n");
SETFLAGS(X_ALL, SF_SET);
- GETEB(x1, 0);
- CALL(idiv8, -1);
+ GETSEB(x1, 0);
+ SXTHw(x2, xRAX);
+ SDIVw(x3, x2, ed);
+ MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
+ BFIx(xRAX, x3, 0, 8);
+ BFIx(xRAX, x4, 8, 8);
break;
}
break;
@@ -2666,7 +2931,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
GETED(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -2680,11 +2944,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
GETED(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -2698,6 +2962,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
break;
case 6:
INST_NAME("DIV Ed");
@@ -2705,16 +2970,28 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(!rex.w) {
SET_DFNONE(x2);
GETED(0);
- MOVw_REG(x3, xRAX);
- ORRx_REG_LSL(x3, x3, xRDX, 32);
- if(MODREG) {
- MOVw_REG(x4, ed);
- ed = x4;
+ if(ninst && (nextop==0xF0)
+ && dyn->insts[ninst-1].x64.addr
+ && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0xB8
+ && *(uint32_t*)(dyn->insts[ninst-1].x64.addr+1)==0) {
+ // hack for some protection that check a divide by zero actualy trigger a divide by zero exception
+ MESSAGE(LOG_INFO, "Divide by 0 hack\n");
+ GETIP(ip);
+ STORE_XEMU_CALL(xRIP);
+ CALL(native_div0, -1);
+ LOAD_XEMU_CALL(xRIP);
+ } else {
+ MOVw_REG(x3, xRAX);
+ ORRx_REG_LSL(x3, x3, xRDX, 32);
+ if(MODREG) {
+ MOVw_REG(x4, ed);
+ ed = x4;
+ }
+ UDIVx(x2, x3, ed);
+ MSUBx(x4, x2, ed, xRAX);
+ MOVw_REG(xRAX, x2);
+ MOVw_REG(xRDX, x4);
}
- UDIVx(x2, x3, ed);
- MSUBx(x4, x2, ed, xRAX);
- MOVw_REG(xRAX, x2);
- MOVw_REG(xRDX, x4);
} else {
if(ninst
&& dyn->insts[ninst-1].x64.addr
@@ -2870,6 +3147,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEDz(0);
if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
BARRIER(BARRIER_FULL);
+ BARRIER_NEXT(BARRIER_FULL);
} else {
BARRIER(BARRIER_FLOAT);
*need_epilog = 0;
@@ -2877,12 +3155,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
GETIP_(addr);
if(box64_dynarec_callret) {
+ SET_HASCALLRET();
// Push actual return address
if(addr < (dyn->start+dyn->isize)) {
// there is a next...
j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
ADR_S20(x4, j64);
+ MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
} else {
+ MESSAGE(LOG_NONE, "\tCALLRET set return to Jmptable(%p)\n", (void*)addr);
j64 = getJumpTableAddress64(addr);
TABLE64(x4, j64);
LDRx_U12(x4, x4, 0);
@@ -2908,12 +3189,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("JMP FAR Ed");
READFLAGS(X_PEND);
BARRIER(BARRIER_FLOAT);
- SMREAD()
+ SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0);
LDxw(x1, wback, 0);
ed = x1;
LDH(x3, wback, rex.w?8:4);
- STW(x3, xEmu, offsetof(x64emu_t, segs[_CS]));
+ STH(x3, xEmu, offsetof(x64emu_t, segs[_CS]));
STW(xZR, xEmu, offsetof(x64emu_t, segs_serial[_CS]));
jump_to_epilog(dyn, 0, ed, ninst);
*need_epilog = 0;
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index e4aa365..3ef6769 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -17,6 +17,7 @@
#include "dynarec_native.h"
#include "my_cpuid.h"
#include "emu/x87emu_private.h"
+#include "emu/x64shaext.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
@@ -302,7 +303,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SMWRITE2();
}
break;
-
+ case 0x2A:
+ INST_NAME("CVTPI2PS Gx,Em");
+ nextop = F8;
+ GETGX(v0, 1);
+ GETEM(q1, 0);
+ d0 = fpu_get_scratch(dyn);
+ u8 = sse_setround(dyn, ninst, x1, x2, x3);
+ SCVTFS(d0, q1);
+ x87_restoreround(dyn, ninst, u8);
+ VMOVeD(v0, 0, d0, 0);
+ break;
case 0x2B:
INST_NAME("MOVNTPS Ex,Gx");
nextop = F8;
@@ -317,7 +328,69 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VST128(v0, ed, fixedaddress);
}
break;
-
+ case 0x2C:
+ INST_NAME("CVTTPS2PI Gm,Ex");
+ nextop = F8;
+ GETGM(q0);
+ GETEX(v1, 0, 0);
+ if (box64_dynarec_fastround) {
+ VFCVTZSS(q0, v1);
+ } else {
+ MRS_fpsr(x5);
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ MSR_fpsr(x5);
+ ORRw_mask(x2, xZR, 1, 0); //0x80000000
+ d0 = fpu_get_scratch(dyn);
+ for (int i=0; i<2; ++i) {
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ if (i) {
+ VMOVeS(d0, 0, v1, i);
+ FRINTZS(d0, d0);
+ } else {
+ FRINTZS(d0, v1);
+ }
+ FCVTZSwS(x1, d0);
+ MRS_fpsr(x5); // get back FPSR to check the IOC bit
+ TBZ(x5, FPSR_IOC, 4+4);
+ MOVw_REG(x1, x2);
+ VMOVQSfrom(q0, i, x1);
+ }
+ }
+ break;
+ case 0x2D:
+ INST_NAME("CVTPS2PI Gm, Ex");
+ nextop = F8;
+ GETGM(q0);
+ GETEX(v1, 0, 0);
+ if (box64_dynarec_fastround) {
+ u8 = sse_setround(dyn, ninst, x1, x2, x3);
+ VFRINTIS(q0, v1);
+ x87_restoreround(dyn, ninst, u8);
+ VFCVTZSS(q0, q0);
+ } else {
+ u8 = sse_setround(dyn, ninst, x1, x2, x3);
+ MRS_fpsr(x5);
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ MSR_fpsr(x5);
+ ORRw_mask(x2, xZR, 1, 0); //0x80000000
+ d0 = fpu_get_scratch(dyn);
+ for (int i=0; i<2; ++i) {
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ if (i) {
+ VMOVeS(d0, 0, v1, i);
+ FRINTIS(d0, d0);
+ } else {
+ FRINTIS(d0, v1);
+ }
+ FCVTZSwS(x1, d0);
+ MRS_fpsr(x5); // get back FPSR to check the IOC bit
+ TBZ(x5, FPSR_IOC, 4+4);
+ MOVw_REG(x1, x2);
+ VMOVQSfrom(q0, i, x1);
+ }
+ x87_restoreround(dyn, ninst, u8);
+ }
+ break;
case 0x2E:
// no special check...
case 0x2F:
@@ -349,11 +422,34 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETGM(q0);
GETEM(q1, 0);
d0 = fpu_get_scratch(dyn);
- MOVI_8(d0, 0b10001111);
+ MOVI_8(d0, 0b10000111);
VAND(d0, d0, q1); // mask the index
VTBL1_8(q0, q0, d0);
break;
-
+ case 0x01:
+ INST_NAME("PHADDW Gm, Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ VADDP_16(q0, q0, q1);
+ break;
+ case 0x2:
+ INST_NAME("PHADDD Gm, Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ VADDP_32(q0, q0, q1);
+ break;
+ case 0x03:
+ INST_NAME("PHADDSW Gm, Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1_16(v0, q0, q1);
+ VUZP2_16(q0, q0, q1);
+ SQADD_16(q0, q0, v0);
+ break;
case 0x04:
INST_NAME("PMADDUBSW Gm,Em");
nextop = F8;
@@ -367,7 +463,75 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SADDLPQ_16(v1, v0);
SQXTN_16(q0, v1);
break;
-
+ case 0x05:
+ INST_NAME("PHSUBW Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1_16(v0, q0, q1);
+ VUZP2_16(q0, q0, q1);
+ VSUB_16(q0, v0, q0);
+ break;
+ case 0x06:
+ INST_NAME("PHSUBD Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1_32(v0, q0, q1);
+ VUZP2_32(q0, q0, q1);
+ VSUB_32(q0, v0, q0);
+ break;
+ case 0x07:
+ INST_NAME("PHSUBSW Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1_16(v0, q0, q1);
+ VUZP2_16(q0, q0, q1);
+ SQSUB_16(q0, v0, q0);
+ break;
+ case 0x08:
+ INST_NAME("PSIGNB Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ v1 = fpu_get_scratch(dyn);
+ CMGT_0_8(v0, q1);
+ VAND(v0, v0, q0);
+ CMLT_0_8(v1, q1);
+ VMUL_8(q0, q0, v1);
+ VORR(q0, q0, v0);
+ break;
+ case 0x09:
+ INST_NAME("PSIGNW Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ v1 = fpu_get_scratch(dyn);
+ CMGT_0_16(v0, q1);
+ VAND(v0, v0, q0);
+ CMLT_0_16(v1, q1);
+ VMUL_16(q0, q0, v1);
+ VORR(q0, q0, v0);
+ break;
+ case 0x0A:
+ INST_NAME("PSIGND Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ v0 = fpu_get_scratch(dyn);
+ v1 = fpu_get_scratch(dyn);
+ CMGT_0_32(v0, q1);
+ VAND(v0, v0, q0);
+ CMLT_0_32(v1, q1);
+ VMUL_32(q0, q0, v1);
+ VORR(q0, q0, v0);
+ break;
case 0x0B:
INST_NAME("PMULHRSW Gm,Em");
nextop = F8;
@@ -375,6 +539,199 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEM(q1, 0);
SQRDMULH_16(q0, q0, q1);
break;
+ case 0x1C:
+ INST_NAME("PABSB Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ ABS_8(q0, q1);
+ break;
+ case 0x1D:
+ INST_NAME("PABSW Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ ABS_16(q0, q1);
+ break;
+ case 0x1E:
+ INST_NAME("PABSD Gm,Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ ABS_32(q0, q1);
+ break;
+
+ case 0xC8:
+ INST_NAME("SHA1NEXTE Gx, Ex");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ VEORQ(v0, v0, v0);
+ if(arm64_sha1) {
+ v1 = fpu_get_scratch(dyn);
+ VMOVeS(v1, 0, q0, 3);
+ SHA1H(v1, v1);
+ VMOVeS(v0, 3, v1, 0);
+ } else {
+ VMOVSto(x1, q0, 3);
+ RORw(x1, x1, 2); // i.e. ROL 30
+ VMOVQSfrom(v0, 3, x1);
+ }
+ VADDQ_32(q0, v0, q1);
+ break;
+ case 0xC9:
+ INST_NAME("SHA1MSG1 Gx, Ex");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ VEXTQ_8(v0, q1, q0, 8);
+ VEORQ(q0, q0, v0);
+ break;
+ case 0xCA:
+ INST_NAME("SHA1MSG2 Gx, Ex");
+ nextop = F8;
+ if(arm64_sha1) {
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ VEXTQ_8(q0, q0, q0, 8);
+ VREV64Q_32(q0, q0);
+ if(MODREG) {
+ if(q0==q1)
+ v0 = q0;
+ else {
+ v0 = fpu_get_scratch(dyn);
+ VEXTQ_8(v0, q1, q1, 8);
+ VREV64Q_32(v0, v0);
+ }
+ } else {
+ v0 = q1;
+ VEXTQ_8(v0, q1, q1, 8);
+ VREV64Q_32(v0, v0);
+ }
+ SHA1SU1(q0, v0);
+ VEXTQ_8(q0, q0, q0, 8);
+ VREV64Q_32(q0, q0);
+ } else {
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+ if(wback!=x2) {
+ MOVx_REG(x2, wback);
+ }
+ }
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+ CALL(sha1msg2, -1);
+ }
+ break;
+ case 0xCB:
+ INST_NAME("SHA256RNDS2 Gx, Ex (, XMM0)");
+ nextop = F8;
+ if(arm64_sha2) {
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ d0 = sse_get_reg(dyn, ninst, x1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ d1 = fpu_get_scratch(dyn);
+ if(MODREG) {
+ v1 = fpu_get_scratch(dyn);
+ } else
+ v1 = q1;
+ VREV64Q_32(q0, q0);
+ VREV64Q_32(v1, q1);
+ VZIP1Q_64(v0, v1, q0);
+ VZIP2Q_64(v1, v1, q0);
+ SHA256H(v1, v0, d0);
+ VREV64Q_32(d1, q1);
+ VZIP2Q_64(d1, d1, q0);
+ SHA256H2(v0, d1, d0);
+ VZIP2Q_64(q0, v0, v1);
+ VREV64Q_32(q0, q0);
+ } else {
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+ if(wback!=x2) {
+ MOVx_REG(x2, wback);
+ }
+ }
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+ sse_reflect_reg(dyn, ninst, 0);
+ CALL(sha256rnds2, -1);
+ }
+ break;
+ case 0xCC:
+ INST_NAME("SHA256MSG1 Gx, Ex");
+ nextop = F8;
+ if(arm64_sha2) {
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ SHA256SU0(q0, q1);
+ } else {
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+ if(wback!=x2) {
+ MOVx_REG(x2, wback);
+ }
+ }
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+ CALL(sha256msg1, -1);
+ }
+ break;
+ case 0xCD:
+ INST_NAME("SHA256MSG2 Gx, Ex");
+ nextop = F8;
+ if(arm64_sha2) {
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ v1 = fpu_get_scratch(dyn);
+ d0 = fpu_get_scratch(dyn);
+ VEORQ(v1, v1, v1);
+ VMOVQ(v0, q0);
+ SHA256SU1(v0, v1, q1); // low v0 are ok and also need to be feed again SHA256SU1 to get the high part
+ VTRNQ1_64(d0, v0, v0); // duplicate low to hi
+ VEXTQ_8(q0, q0, q0, 8); // invert low/high now
+ SHA256SU1(q0, v1, d0); // low is destination high
+ VEXTQ_8(q0, d0, q0, 8);
+ } else {
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+ if(wback!=x2) {
+ MOVx_REG(x2, wback);
+ }
+ }
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+ CALL(sha256msg2, -1);
+ }
+ break;
case 0xF0:
INST_NAME("MOVBE Gd, Ed");
@@ -427,6 +784,81 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VEXT_8(q0, q1, q0, u8);
}
break;
+
+ case 0xCC:
+ INST_NAME("SHA1RNDS4 Gx, Ex, Ib");
+ nextop = F8;
+ if(arm64_sha1) {
+ GETGX(q0, 1);
+ GETEX(q1, 0, 1);
+ u8 = F8&3;
+ d0 = fpu_get_scratch(dyn);
+ d1 = fpu_get_scratch(dyn);
+ v0 = fpu_get_scratch(dyn);
+ VEXTQ_8(v0, q0, q0, 8);
+ VREV64Q_32(v0, v0);
+ VEORQ(d1, d1, d1);
+ if(MODREG) {
+ if(q0==q1)
+ v1 = v0;
+ else
+ v1 = fpu_get_scratch(dyn);
+ } else
+ v1 = q1;
+ if(v1!=v0) {
+ VEXTQ_8(v1, q1, q1, 8);
+ VREV64Q_32(v1, v1);
+ }
+ switch(u8) {
+ case 0:
+ MOV32w(x1, 0x5A827999);
+ VDUPQS(d0, x1);
+ VADDQ_32(v1, v1, d0);
+ SHA1C(v0, d1, v1);
+ break;
+ case 1:
+ MOV32w(x1, 0x6ED9EBA1);
+ VDUPQS(d0, x1);
+ VADDQ_32(v1, v1, d0);
+ SHA1P(v0, d1, v1);
+ break;
+ case 2:
+ MOV32w(x1, 0X8F1BBCDC);
+ VDUPQS(d0, x1);
+ VADDQ_32(v1, v1, d0);
+ SHA1M(v0, d1, v1);
+ break;
+ case 3:
+ MOV32w(x1, 0xCA62C1D6);
+ VDUPQS(d0, x1);
+ VADDQ_32(v1, v1, d0);
+ SHA1P(v0, d1, v1);
+ break;
+ }
+ VREV64Q_32(v0, v0);
+ VEXTQ_8(q0, v0, v0, 8);
+ break;
+ } else {
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+ if(wback!=x2) {
+ MOVx_REG(x2, wback);
+ }
+ }
+ u8 = F8;
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+ MOV32w(x3, u8);
+ CALL(sha1rnds4, -1);
+ }
+ break;
+
default:
DEFAULT;
}
@@ -787,33 +1219,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VMOVeS(v0, 1, v1, 0);
}
} else if(u8==0x00) {
- // dumplicate lower 16bits to all spot
- if(v0!=v1) {
- VMOVeH(v0, 0, v1, 0);
- }
- VMOVeH(v0, 1, v1, 0);
- VMOVeS(v0, 1, v1, 0);
+ // duplicate lower 16bits to all spot
+ VDUP_16(v0, v1, 0);
} else if(u8==0x55) {
- // dumplicate 16bits slot 1 to all spot
- if(v0!=v1) {
- VMOVeH(v0, 1, v1, 1);
- }
- VMOVeH(v0, 0, v1, 1);
- VMOVeS(v0, 1, v1, 0);
+ // duplicate 16bits slot 1 to all spot
+ VDUP_16(v0, v1, 1);
} else if(u8==0xAA) {
- // dumplicate 16bits slot 2 to all spot
- if(v0!=v1) {
- VMOVeH(v0, 2, v1, 2);
- }
- VMOVeH(v0, 3, v1, 2);
- VMOVeS(v0, 0, v1, 1);
+ // duplicate 16bits slot 2 to all spot
+ VDUP_16(v0, v1, 2);
} else if(u8==0xFF) {
- // dumplicate 16bits slot 3 to all spot
- if(v0!=v1) {
- VMOVeH(v0, 3, v1, 3);
- }
- VMOVeH(v0, 2, v1, 3);
- VMOVeS(v0, 0, v1, 1);
+ // duplicate 16bits slot 3 to all spot
+ VDUP_16(v0, v1, 3);
} else if(v0!=v1) {
VMOVeH(v0, 0, v1, (u8>>(0*2))&3);
VMOVeH(v0, 1, v1, (u8>>(1*2))&3);
@@ -1133,13 +1549,27 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xA5:
nextop = F8;
INST_NAME("SHLD Ed, Gd, CL");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- UXTBw(x3, xRCX);
- SETFLAGS(X_ALL, SF_SET);
- GETEDW(x4, x1, 0);
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
GETGD;
- MOVxw_REG(x2, gd);
- CALL_(rex.w?((void*)shld64):((void*)shld32), ed, x4);
+ GETED(0);
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ B_NEXT(cEQ);
+ } else {
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ }
+ emit_shld32(dyn, ninst, rex, ed, gd, x3, x5, x4);
WBACK;
break;
@@ -1166,17 +1596,13 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f
}
- LSRxw_REG(x4, ed, x2);
- if(rex.w) {
- ANDSx_mask(x4, x4, 1, 0, 0); //mask=1
- } else {
- ANDSw_mask(x4, x4, 0, 0); //mask=1
+ IFX(X_CF) {
+ LSRxw_REG(x4, ed, x2);
+ BFIw(xFlags, x4, F_CF, 1);
}
- BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
- EORxw_REG(x4, ed, x4);
- CSELxw(ed, ed, x4, cNE);
+ ORRxw_REG(ed, ed, x4);
if(wback) {
STRxw_U12(ed, wback, fixedaddress);
SMWRITE();
@@ -1195,13 +1621,27 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xAD:
nextop = F8;
INST_NAME("SHRD Ed, Gd, CL");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_ALL, SF_SET);
- UXTBw(x3, xRCX);
- GETEDW(x4, x1, 0);
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
GETGD;
- MOVxw_REG(x2, gd);
- CALL_(rex.w?((void*)shrd64):((void*)shrd32), ed, x4);
+ GETED(0);
+ if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
+ UFLAG_IF {
+ if(rex.w) {
+ ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ B_NEXT(cEQ);
+ } else {
+ if(rex.w) {
+ ANDx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
+ } else {
+ ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
+ }
+ }
+ emit_shrd32(dyn, ninst, rex, ed, gd, x3, x5, x4);
WBACK;
break;
@@ -1279,7 +1719,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xAF:
INST_NAME("IMUL Gd, Ed");
- SETFLAGS(X_ALL, SF_PENDING);
+ SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
GETED(0);
@@ -1288,9 +1728,20 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_IF {
SMULH(x3, gd, ed);
MULx(gd, gd, ed);
- UFLAG_OP1(x3);
- UFLAG_RES(gd);
- UFLAG_DF(x3, d_imul64);
+ IFX(X_PEND) {
+ UFLAG_OP1(x3);
+ UFLAG_RES(gd);
+ UFLAG_DF(x4, d_imul64);
+ } else IFX(X_CF|X_OF) {
+ SET_DFNONE(x4);
+ }
+ IFX(X_CF|X_OF) {
+ ASRx(x4, gd, 63);
+ CMPSx_REG(x3, x4);
+ CSETw(x3, cNE);
+ BFIw(xFlags, x3, F_CF, 1);
+ BFIw(xFlags, x3, F_OF, 1);
+ }
} else {
MULxw(gd, gd, ed);
}
@@ -1298,10 +1749,29 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
// 32bits imul
UFLAG_IF {
SMULL(gd, gd, ed);
- UFLAG_RES(gd);
- LSRx(x3, gd, 32);
- UFLAG_OP1(x3);
- UFLAG_DF(x3, d_imul32);
+ IFX(X_PEND) {
+ UFLAG_RES(gd);
+ LSRx(x3, gd, 32);
+ UFLAG_OP1(x3);
+ UFLAG_DF(x4, d_imul32);
+ } else IFX(X_CF|X_OF) {
+ SET_DFNONE(x4);
+ }
+ IFX(X_CF|X_OF) {
+ ASRx(x3, gd, 31);
+ ASRw(x4, gd, 31);
+ CMPSw_REG(x3, x4);
+ CSETw(x3, cNE);
+ BFIw(xFlags, x3, F_CF, 1);
+ BFIw(xFlags, x3, F_OF, 1);
+ }
+ if(box64_dynarec_test) {
+ // to avoid noise during test
+ BFCw(xFlags, F_AF, 1);
+ BFCw(xFlags, F_PF, 1);
+ BFCw(xFlags, F_ZF, 1);
+ BFCw(xFlags, F_SF, 1);
+ }
MOVw_REG(gd, gd);
} else {
MULxw(gd, gd, ed);
@@ -1332,13 +1802,10 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f
}
- LSRxw_REG(x4, ed, x2);
- if(rex.w) {
- ANDx_mask(x4, x4, 1, 0, 0); //mask=1
- } else {
- ANDw_mask(x4, x4, 0, 0); //mask=1
+ IFX(X_CF) {
+ LSRxw_REG(x4, ed, x2);
+ BFIw(xFlags, x4, F_CF, 1);
}
- BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
BICxw_REG(ed, ed, x4);
@@ -1417,15 +1884,15 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
u8 = F8;
u8&=(rex.w?0x3f:0x1f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
- TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
MOV32w(x4, 1);
ORRxw_REG_LSL(ed, ed, x4, u8);
if(wback) {
STxw(ed, wback, fixedaddress);
SMWRITE();
}
- MARK3;
break;
case 6:
INST_NAME("BTR Ed, Ib");
@@ -1442,15 +1909,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
u8 = F8;
u8&=(rex.w?0x3f:0x1f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
- TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction
- MOV32w(x4, 1);
- BICxw_REG_LSL(ed, ed, x4, u8);
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
+ BFCxw(ed, u8, 1);
if(wback) {
STxw(ed, wback, fixedaddress);
SMWRITE();
}
- MARK3;
break;
case 7:
INST_NAME("BTC Ed, Ib");
@@ -1467,14 +1933,15 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
u8 = F8;
u8&=(rex.w?0x3f:0x1f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
if(wback) {
STxw(ed, wback, fixedaddress);
SMWRITE();
}
- MARK3;
break;
default:
DEFAULT;
@@ -1503,13 +1970,10 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f
}
- LSRxw_REG(x4, ed, x2);
- if(rex.w) {
- ANDx_mask(x4, x4, 1, 0, 0); //mask=1
- } else {
- ANDw_mask(x4, x4, 0, 0); //mask=1
+ IFX(X_CF) {
+ LSRxw_REG(x4, ed, x2);
+ BFIw(xFlags, x4, F_CF, 1);
}
- BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
EORxw_REG(ed, ed, x4);
@@ -1780,12 +2244,13 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop = F8;
GETGM(d0);
GETEM(d1, 0);
- if(MODREG)
- q0 = fpu_get_scratch(dyn);
- else
- q0 = d1;
- NEG_64(q0, d1);
- USHL_R_64(d0, d0, q0);
+ v0 = fpu_get_scratch(dyn);
+ //MOVI_64(v0, 64); not 64!
+ MOV32w(x1, 64);
+ VMOVQDfrom(v0, 0, x1);
+ UMIN_32(v0, v0, d1); // limit to 0 .. +64 values (will force 32bits upper part to 0)
+ NEG_64(v0, v0);
+ USHL_R_64(d0, d0, v0);
break;
case 0xD4:
INST_NAME("PADDQ Gm,Em");
@@ -1975,7 +2440,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VEOR(q0, q0, q1);
}
break;
-
+ case 0xF1:
+ INST_NAME("PSLLW Gm,Em");
+ nextop = F8;
+ GETGM(d0);
+ GETEM(d1, 0);
+ v0 = fpu_get_scratch(dyn);
+ VMOVHto(x1, d1, 0);
+ VDUPH(v0, x1);
+ USHL_16(d0, d0, v0);
+ break;
case 0xF2:
INST_NAME("PSLLD Gm,Em");
nextop = F8;
@@ -1987,11 +2461,18 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SQXTN_32(v0, v0); // 2*q1 in 32bits now
SSHL_32(d0, d0, v0);
break;
+ case 0xF3:
+ INST_NAME("PSLLQ Gm,Em");
+ nextop = F8;
+ GETGM(d0);
+ GETEM(d1, 0);
+ USHL_R_64(d0, d0, d1);
+ break;
case 0xF4:
- INST_NAME("PMULUDQ Gx,Ex");
+ INST_NAME("PMULUDQ Gm,Em");
nextop = F8;
- GETGX(v0, 1);
- GETEX(v1, 0, 0);
+ GETGM(v0);
+ GETEM(v1, 0);
VUMULL_32(v0, v0, v1);
break;
case 0xF5:
@@ -2016,7 +2497,20 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UADDLVQ_16(d1, d0);
VMOVeD(q0, 0, d1, 0);
break;
-
+ case 0xF7:
+ INST_NAME("MASKMOVQ Gm, Em");
+ nextop = F8;
+ GETGM(q0);
+ GETEM(q1, 0);
+ d0 = fpu_get_scratch(dyn);
+ d1 = fpu_get_scratch(dyn);
+ VSSHR_8(d1, q1, 7); // d1 = byte slection mask
+ VLDR64_U12(d0, xRDI, 0);
+ VBIC(d0, d0, d1); // d0 = clear masked byte
+ VAND(d1, q0, d1); // d1 = masked Gm
+ VORR(d0, d0, d1);
+ VSTR64_U12(d0, xRDI, 0);
+ break;
case 0xF8:
INST_NAME("PSUBB Gm, Em");
nextop = F8;
@@ -2038,20 +2532,19 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEM(v1, 0);
VSUB_32(v0, v0, v1);
break;
-
- case 0xFC:
- INST_NAME("PADDB Gm, Em");
+ case 0xFB:
+ INST_NAME("PSUBQ Gm, Em");
nextop = F8;
GETGM(v0);
GETEM(v1, 0);
- VADD_8(v0, v0, v1);
+ SUB_64(v0, v0, v1);
break;
- case 0xFB:
- INST_NAME("PSUBQ Gm, Em");
+ case 0xFC:
+ INST_NAME("PADDB Gm, Em");
nextop = F8;
GETGM(v0);
GETEM(v1, 0);
- SUB_64(v0, v0, v1);
+ VADD_8(v0, v0, v1);
break;
case 0xFD:
INST_NAME("PADDW Gm, Em");
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index d88f3b6..1c8343b 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -58,6 +58,16 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch(opcode) {
+ case 0x01:
+ INST_NAME("ADD Seg:Ed, Gd");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ GETGD;
+ GETEDO(x4, 0);
+ emit_add32(dyn, ninst, rex, ed, gd, x3, x5);
+ WBACKO(x4);
+ break;
case 0x03:
INST_NAME("ADD Gd, Seg:Ed");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -223,8 +233,8 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_RES(gd);
LSRx(x3, gd, 32);
UFLAG_OP1(x3);
- UFLAG_DF(x3, d_imul32);
MOVw_REG(gd, gd);
+ UFLAG_DF(x3, d_imul32);
} else {
MULxw(gd, gd, ed);
}
@@ -268,6 +278,28 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
+ case 0x21:
+ INST_NAME("AND Seg:Ed, Gd");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ GETGD;
+ GETEDO(x4, 0);
+ emit_and32(dyn, ninst, rex, ed, gd, x3, x5);
+ WBACKO(x4);
+ break;
+
+ case 0x29:
+ INST_NAME("SUB Seg:Ed, Gd");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ GETGD;
+ GETEDO(x4, 0);
+ emit_sub32(dyn, ninst, rex, ed, gd, x3, x5);
+ WBACKO(x4);
+ break;
+
case 0x2B:
INST_NAME("SUB Gd, Seg:Ed");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -278,6 +310,17 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_sub32(dyn, ninst, rex, gd, ed, x3, x4);
break;
+ case 0x31:
+ INST_NAME("XOR Seg:Ed, Gd");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ GETGD;
+ GETEDO(x4, 0);
+ emit_xor32(dyn, ninst, rex, ed, gd, x3, x5);
+ WBACKO(x4);
+ break;
+
case 0x33:
INST_NAME("XOR Gd, Seg:Ed");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -337,10 +380,22 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
break;
-
+ case 0x64:
+ addr = dynarec64_64(dyn, addr, ip, ninst, rex, rep, _FS, ok, need_epilog);
+ break;
+ case 0x65:
+ addr = dynarec64_64(dyn, addr, ip, ninst, rex, rep, _GS, ok, need_epilog);
+ break;
case 0x66:
addr = dynarec64_6664(dyn, addr, ip, ninst, rex, seg, ok, need_epilog);
break;
+ case 0x67:
+ if(rex.is32bits)
+ addr = dynarec64_6764_32(dyn, addr, ip, ninst, rex, rep, seg, ok, need_epilog);
+ else {
+ DEFAULT;
+ }
+ break;
case 0x80:
nextop = F8;
@@ -514,7 +569,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
gd = (nextop&0x38)>>3;
gb1 = xRAX+(gd&3);
- gb2 = ((gd&4)>>2);
+ gb2 = ((gd&4)<<1);
}
if(MODREG) {
if(rex.rex) {
@@ -538,7 +593,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LDRB_REG(x4, wback, x4);
ed = x4;
}
- BFIx(gb1, ed, gb2*8, 8);
+ BFIx(gb1, ed, gb2, 8);
break;
case 0x89:
INST_NAME("MOV Seg:Ed, Gd");
@@ -584,7 +639,22 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
break;
-
+ case 0x8E:
+ INST_NAME("MOV Seg,Ew");
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ u8 = (nextop&0x38)>>3;
+ if((nextop&0xC0)==0xC0) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+ LDRH_REG(x1, wback, x4);
+ ed = x1;
+ }
+ STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+ STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
+ break;
case 0x8F:
INST_NAME("POP FS:Ed");
grab_segdata(dyn, addr, ninst, x4, seg);
@@ -604,6 +674,9 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
break;
+ case 0x90:
+ INST_NAME("NOP");
+ break;
case 0xA1:
INST_NAME("MOV EAX,FS:Od");
@@ -902,7 +975,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
GETEDO(x6, 0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -916,11 +988,11 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
GETEDO(x6, 0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -934,6 +1006,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
break;
case 6:
INST_NAME("DIV Ed");
@@ -1048,6 +1121,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEDOz(x6, 0);
if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
BARRIER(BARRIER_FULL);
+ BARRIER_NEXT(BARRIER_FULL);
} else {
BARRIER(BARRIER_FLOAT);
*need_epilog = 0;
@@ -1055,12 +1129,15 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
GETIP_(addr);
if(box64_dynarec_callret) {
+ SET_HASCALLRET();
// Push actual return address
if(addr < (dyn->start+dyn->isize)) {
// there is a next...
j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
ADR_S20(x4, j64);
+ MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2);
} else {
+ MESSAGE(LOG_NONE, "\tCALLRET set return to Jmptable(%p)\n", (void*)addr);
j64 = getJumpTableAddress64(addr);
TABLE64(x4, j64);
LDRx_U12(x4, x4, 0);
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index f646a28..6d77a3c 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -15,6 +15,7 @@
#include "emu/x64run_private.h"
#include "x64trace.h"
#include "dynarec_native.h"
+#include "custommem.h"
#include "arm64_printer.h"
#include "dynarec_arm64_private.h"
@@ -42,7 +43,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MAYUSE(j64);
MAYUSE(lock);
- while((opcode==0x2E) || (opcode==0x36) || (opcode==0x66)) // ignoring CS:, SS: or multiple 0x66
+ while((opcode==0x2E) || (opcode==0x36) || (opcode==0x26) || (opcode==0x66)) // ignoring CS:, SS:, ES: or multiple 0x66
opcode = F8;
while((opcode==0xF2) || (opcode==0xF3)) {
@@ -82,6 +83,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_add16(dyn, ninst, x1, x2, x3, x4);
BFIx(xRAX, x1, 0, 16);
break;
+ case 0x06:
+ if(rex.is32bits) {
+ INST_NAME("PUSH ES");
+ LDRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_ES]));
+ PUSH1_32(x1);
+ } else {
+ DEFAULT;
+ }
+ break;
+ case 0x07:
+ if(rex.is32bits) {
+ INST_NAME("POP ES");
+ POP1_32(x1);
+ STRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_ES]));
+ STRw_U12(xZR, xEmu, offsetof(x64emu_t, segs_serial[_ES]));
+ } else {
+ DEFAULT;
+ }
+ break;
case 0x09:
INST_NAME("OR Ew, Gw");
@@ -112,7 +132,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0x0F:
- addr = dynarec64_660F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ switch(rep) {
+ case 0: addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ case 1: addr = dynarec64_66F20F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ case 2: addr = dynarec64_66F30F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ }
break;
case 0x11:
INST_NAME("ADC Ew, Gw");
@@ -175,6 +199,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_sbb16(dyn, ninst, x1, x2, x3, x4);
BFIx(xRAX, x1, 0, 16);
break;
+ case 0x1E:
+ if(rex.is32bits) {
+ INST_NAME("PUSH DS");
+ LDRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_DS]));
+ PUSH1_32(x1);
+ } else {
+ DEFAULT;
+ }
+ break;
+ case 0x1F:
+ if(rex.is32bits) {
+ INST_NAME("POP DS");
+ POP1_32(x1);
+ STRH_U12(x1, xEmu, offsetof(x64emu_t, segs[_DS]));
+ STRw_U12(xZR, xEmu, offsetof(x64emu_t, segs_serial[_DS]));
+ } else {
+ DEFAULT;
+ }
+ break;
case 0x21:
INST_NAME("AND Ew, Gw");
@@ -330,7 +373,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(rex.is32bits) {
INST_NAME("PUSH reg");
gd = xRAX+(opcode&0x07);
- if (gd == xRSP) {
+ if (gd==xRSP) {
MOVw_REG(x1, xRSP);
PUSH1_16(x1);
} else {
@@ -415,7 +458,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
SETFLAGS(X_ALL, SF_PENDING);
nextop = F8;
- UFLAG_DF(x1, d_imul16);
GETSEW(x1, (opcode==0x69)?2:1);
if(opcode==0x69) i32 = F16S; else i32 = F8S;
MOV32w(x2, i32);
@@ -423,6 +465,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_RES(x2);
gd=x2;
GWBACK;
+ UFLAG_DF(x1, d_imul16);
break;
case 0x70:
@@ -548,19 +591,36 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
GETGD;
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- SMDMB();
- TSTx_mask(ed, 1, 0, 0); // mask=1
- B_MARK(cNE);
- MARKLOCK;
- LDAXRH(x1, ed);
- STLXRH(x3, gd, ed);
- CBNZx_MARKLOCK(x3);
- B_MARK2_nocond;
- MARK;
- LDRH_U12(x1, ed, 0);
- STRH_U12(gd, ed, 0);
- MARK2;
- SMDMB();
+ if(!ALIGNED_ATOMICH) {
+ TSTx_mask(ed, 1, 0, 0); // mask=1
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ SWPALH(gd, x1, ed);
+ SMDMB();
+ if(!ALIGNED_ATOMICH) {
+ B_MARK2_nocond;
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, ed);
+ STLXRH(x3, gd, ed);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ if(!ALIGNED_ATOMICH) {
+ B_MARK2_nocond;
+ }
+ }
+ if(!ALIGNED_ATOMICH) {
+ MARK;
+ LDRH_U12(x1, ed, 0);
+ LDAXRB(x3, ed);
+ STLXRB(x3, gd, ed);
+ CBNZx_MARK(x3);
+ STRH_U12(gd, ed, 0);
+ SMDMB();
+ MARK2;
+ }
BFIx(gd, x1, 0, 16);
}
break;
@@ -600,7 +660,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("MOV EW, Seg");
nextop=F8;
u8 = (nextop&0x38)>>3;
- LDRw_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
+ LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
if((nextop&0xC0)==0xC0) { // reg <= seg
UXTHw(xRAX+(nextop&7)+(rex.b<<3), x3);
} else { // mem <= seg
@@ -610,6 +670,22 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
+ case 0x8E:
+ INST_NAME("MOV Seg,Ew");
+ nextop = F8;
+ u8 = (nextop&0x38)>>3;
+ if((nextop&0xC0)==0xC0) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
+ LDH(x1, wback, fixedaddress);
+ ed = x1;
+ }
+ STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+ STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
+ break;
+
case 0x90:
case 0x91:
case 0x92:
@@ -634,7 +710,11 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SXTBw(x1, xRAX);
BFIx(xRAX, x1, 0, 16);
break;
-
+ case 0x99:
+ INST_NAME("CWD");
+ SXTHw(x1, xRAX);
+ BFXILx(xRDX, x1, 16, 16);
+ break;
case 0x9C:
INST_NAME("PUSHF");
READFLAGS(X_ALL);
@@ -665,7 +745,8 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
- SMREAD();
+ if(isLockAddress(u64)) lock=1; else lock = 0;
+ SMREADLOCK(lock);
LDRH_U12(x2, x1, 0);
BFIx(xRAX, x2, 0, 16);
break;
@@ -677,8 +758,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
else
u64 = F64;
MOV64z(x1, u64);
+ if(isLockAddress(u64)) lock=1; else lock = 0;
STRH_U12(xRAX, x1, 0);
- SMWRITE();
+ SMWRITELOCK(lock);
break;
case 0xA5:
@@ -864,23 +946,29 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ew, Ib");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
- GETEW(x1, 1);
- u8 = F8;
- MOV32w(x2, u8);
- CALL_(rol16, x1, x3);
- EWBACK;
+ if(geted_ib(dyn, addr, ninst, nextop)&15) {
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEW(x1, 1);
+ u8 = F8;
+ emit_rol16c(dyn, ninst, x1, u8&15, x4, x5);
+ EWBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 1:
INST_NAME("ROR Ew, Ib");
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_OF|X_CF, SF_SET);
- GETEW(x1, 1);
- u8 = F8;
- MOV32w(x2, u8);
- CALL_(ror16, x1, x3);
- EWBACK;
+ if(geted_ib(dyn, addr, ninst, nextop)&15) {
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEW(x1, 1);
+ u8 = F8;
+ emit_ror16c(dyn, ninst, x1, u8&15, x4, x5);
+ EWBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 2:
INST_NAME("RCL Ew, Ib");
@@ -907,42 +995,42 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
case 6:
INST_NAME("SHL Ew, Ib");
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- SETFLAGS(X_ALL, SF_PENDING);
- GETEW(x1, 1);
- u8 = F8;
- UFLAG_IF {MOV32w(x2, (u8&0x1f));}
- UFLAG_OP12(ed, x2)
- LSLw_IMM(ed, ed, u8&0x1f);
- EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shl16);
+ if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ GETEW(x1, 0);
+ u8 = (F8)&0x1f;
+ emit_shl16c(dyn, ninst, x1, u8, x5, x4);
+ EWBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 5:
INST_NAME("SHR Ed, Ib");
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- SETFLAGS(X_ALL, SF_PENDING);
- GETEW(x1, 1);
- u8 = F8;
- UFLAG_IF {MOV32w(x2, (u8&0x1f));}
- UFLAG_OP12(ed, x2)
- LSRw_IMM(ed, ed, u8&0x1f);
- EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shr16);
+ if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ GETEW(x1, 0);
+ u8 = (F8)&0x1f;
+ emit_shr16c(dyn, ninst, x1, u8, x5, x4);
+ EWBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
case 7:
INST_NAME("SAR Ed, Ib");
- SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- GETSEW(x1, 1);
- u8 = F8;
- UFLAG_IF {MOV32w(x2, (u8&0x1f));}
- UFLAG_OP12(ed, x2)
- ASRw(ed, ed, (u8&0x1f));
- EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_sar16);
+ if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ GETSEW(x1, 0);
+ u8 = (F8)&0x1f;
+ emit_sar16c(dyn, ninst, x1, u8, x5, x4);
+ EWBACK;
+ } else {
+ FAKEED;
+ F8;
+ }
break;
}
break;
@@ -965,108 +1053,186 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xD1:
- case 0xD3:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
- if(opcode==0xD1) {
- INST_NAME("ROL Ew, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("ROL Ew, CL");
- ANDw_mask(x2, xRCX, 0, 0b00100);
- }
+ INST_NAME("ROL Ew, 1");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEW(x1, 0);
+ emit_rol16c(dyn, ninst, x1, 1, x5, x4);
+ EWBACK;
+ break;
+ case 1:
+ INST_NAME("ROR Ew, 1");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+ GETEW(x1, 0);
+ emit_ror16c(dyn, ninst, x1, 1, x5, x4);
+ EWBACK;
+ break;
+ case 2:
+ INST_NAME("RCL Ew, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
+ MOV32w(x2, 1);
GETEW(x1, 0);
- CALL_(rol16, x1, x3);
+ CALL_(rcl16, x1, x3);
EWBACK;
break;
- case 1:
- if(opcode==0xD1) {
- INST_NAME("ROR Ew, 1");
- MOV32w(x2, 1);
- } else {
- INST_NAME("ROR Ew, CL");
- ANDw_mask(x2, xRCX, 0, 0b00100);
- }
+ case 3:
+ INST_NAME("RCR Ew, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
+ MOV32w(x2, 1);
+ GETEW(x1, 0);
+ CALL_(rcr16, x1, x3);
+ EWBACK;
+ break;
+ case 4:
+ case 6:
+ INST_NAME("SHL Ew, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEW(x1, 0);
- CALL_(ror16, x1, x3);
+ emit_shl16c(dyn, ninst, x1, 1, x5, x4);
EWBACK;
break;
+ case 5:
+ INST_NAME("SHR Ew, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ GETEW(x1, 0);
+ emit_shr16c(dyn, ninst, x1, 1, x5, x4);
+ EWBACK;
+ break;
+ case 7:
+ INST_NAME("SAR Ew, 1");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ GETSEW(x1, 0);
+ emit_sar16c(dyn, ninst, x1, 1, x5, x4);
+ EWBACK;
+ break;
+ }
+ break;
+
+ case 0xD3:
+ nextop = F8;
+ switch((nextop>>3)&7) {
+ case 0:
+ INST_NAME("ROL Ew, CL");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ }
+ ANDw_mask(x2, xRCX, 0, 0b00011); //mask=0x00000000f
+ MOV32w(x4, 16);
+ SUBx_REG(x2, x4, x2);
+ GETEW(x1, 0);
+ ORRw_REG_LSL(ed, ed, ed, 16);
+ LSRw_REG(ed, ed, x2);
+ EWBACK;
+ UFLAG_IF { // calculate flags directly
+ CMPSw_U12(x2, 15);
+ B_MARK(cNE);
+ ADDxw_REG_LSR(x3, ed, ed, 15);
+ BFIw(xFlags, x3, F_OF, 1);
+ MARK;
+ BFIw(xFlags, ed, F_CF, 1);
+ UFLAG_DF(x2, d_none);
+ }
+ break;
+ case 1:
+ INST_NAME("ROR Ew, CL");
+ SETFLAGS(X_OF|X_CF, SF_SUBSET);
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ }
+ ANDw_mask(x2, xRCX, 0, 0b00011); //mask=0x00000000f
+ GETEW(x1, 0);
+ ORRw_REG_LSL(ed, ed, ed, 16);
+ LSRw_REG(ed, ed, x2);
+ EWBACK;
+ UFLAG_IF { // calculate flags directly
+ CMPSw_U12(x2, 1);
+ B_MARK(cNE);
+ LSRxw(x2, ed, 14); // x2 = d>>14
+ EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>14) ^ ((d>>14)>>1))
+ BFIw(xFlags, x2, F_OF, 1);
+ MARK;
+ BFXILw(xFlags, ed, 15, 1);
+ UFLAG_DF(x2, d_none);
+ }
+ break;
case 2:
- if(opcode==0xD1) {INST_NAME("RCL Ew, 1"); } else { INST_NAME("RCL Ew, CL");}
+ INST_NAME("RCL Ew, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
- if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);}
+ ANDw_mask(x2, xRCX, 0, 0b00100);
GETEW(x1, 0);
CALL_(rcl16, x1, x3);
EWBACK;
break;
case 3:
- if(opcode==0xD1) {INST_NAME("RCR Ew, 1");} else {INST_NAME("RCR Ew, CL");}
+ INST_NAME("RCR Ew, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
- if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);}
+ ANDw_mask(x2, xRCX, 0, 0b00100);
GETEW(x1, 0);
CALL_(rcr16, x1, x3);
EWBACK;
break;
case 4:
case 6:
- if(opcode==0xD1) {
- INST_NAME("SHL Ew, 1");
- MOV32w(x4, 1);
+ INST_NAME("SHL Ew, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
} else {
- INST_NAME("SHL Ew, CL");
- ANDw_mask(x4, xRCX, 0, 0b00100);
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
}
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- SETFLAGS(X_ALL, SF_PENDING);
GETEW(x1, 0);
- UFLAG_OP12(ed, x4)
- LSLw_REG(ed, ed, x4);
+ emit_shl16(dyn, ninst, x1, x2, x5, x4);
EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shl16);
break;
case 5:
- if(opcode==0xD1) {
- INST_NAME("SHR Ew, 1");
- MOV32w(x4, 1);
+ INST_NAME("SHR Ew, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
} else {
- INST_NAME("SHR Ew, CL");
- ANDw_mask(x4, xRCX, 0, 0b00100);
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
}
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- SETFLAGS(X_ALL, SF_PENDING);
GETEW(x1, 0);
- UFLAG_OP12(ed, x4)
- LSRw_REG(ed, ed, x4);
+ emit_shr16(dyn, ninst, x1, x2, x5, x4);
EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_shr16);
break;
case 7:
- if(opcode==0xD1) {
- INST_NAME("SAR Ew, 1");
- MOV32w(x4, 1);
+ INST_NAME("SAR Ew, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
+ UFLAG_IF {
+ ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
} else {
- INST_NAME("SAR Ew, CL");
- ANDw_mask(x4, xRCX, 0, 0b00100);
+ ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
}
- UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}
- SETFLAGS(X_ALL, SF_PENDING);
GETSEW(x1, 0);
- UFLAG_OP12(ed, x4)
- ASRw_REG(ed, ed, x4);
+ emit_sar16(dyn, ninst, x1, x2, x5, x4);
EWBACK;
- UFLAG_RES(ed);
- UFLAG_DF(x3, d_sar16);
break;
}
break;
@@ -1102,24 +1268,24 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
INST_NAME("MUL AX, Ew");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x1, d_mul16);
GETEW(x1, 0);
UXTHw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIx(xRAX, x1, 0, 16);
BFXILx(xRDX, x1, 16, 16);
+ UFLAG_DF(x1, d_mul16);
break;
case 5:
INST_NAME("IMUL AX, Ew");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x1, d_imul16);
GETSEW(x1, 0);
SXTHw(x2, xRAX);
MULw(x1, x2, x1);
UFLAG_RES(x1);
BFIx(xRAX, x1, 0, 16);
BFXILx(xRDX, x1, 16, 16);
+ UFLAG_DF(x1, d_imul16);
break;
case 6:
INST_NAME("DIV Ew");
@@ -1134,7 +1300,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 7:
INST_NAME("IDIV Ew");
- NOTEST(x1);
+ SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
GETSEW(x1, 0);
UXTHw(x2, xRAX);
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index 9f30df5..bb83384 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -20,10 +20,11 @@
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
+#include "emu/x64compstrings.h"
-uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
- (void)ip; (void)rep; (void)need_epilog;
+ (void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
@@ -48,6 +49,8 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
MAYUSE(j64);
#if STEP > 1
static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
+ static const int8_t mask_string8[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
+ static const int8_t mask_string16[] = { 15, 14, 13, 12, 11, 10, 9, 8 };
static const int8_t round_round[] = { 0, 2, 1, 3};
#endif
@@ -169,7 +172,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
FAKEED;
break;
-
+
case 0x28:
INST_NAME("MOVAPD Gx,Ex");
nextop = F8;
@@ -201,7 +204,92 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SMWRITE2();
}
break;
-
+ case 0x2A:
+ INST_NAME("CVTPI2PD Gx,Em");
+ nextop = F8;
+ GETGX(v0, 1);
+ GETEM(q1, 0);
+ SXTL_32(v0, q1);
+ SCVTQFD(v0, v0);
+ break;
+ case 0x2B:
+ INST_NAME("MOVNTPD Ex,Gx");
+ nextop = F8;
+ GETGX(v0, 0);
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ v1 = sse_get_reg_empty(dyn, ninst, x1, ed);
+ VMOVQ(v1, v0);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
+ VST128(v0, ed, fixedaddress);
+ }
+ break;
+ case 0x2C:
+ INST_NAME("CVTTPD2PI Gm,Ex");
+ nextop = F8;
+ GETGM(q0);
+ GETEX(v1, 0, 0);
+ if(box64_dynarec_fastround) {
+ VFCVTZSQD(q0, v1);
+ SQXTN_32(q0, q0);
+ } else {
+ MRS_fpsr(x5);
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ MSR_fpsr(x5);
+ ORRw_mask(x2, xZR, 1, 0); //0x80000000
+ d0 = fpu_get_scratch(dyn);
+ for (int i=0; i<2; ++i) {
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ if (i) {
+ VMOVeD(d0, 0, v1, i);
+ FRINTZD(d0, d0);
+ } else {
+ FRINTZD(d0, v1);
+ }
+ FCVTZSwD(x1, d0);
+ MRS_fpsr(x5); // get back FPSR to check the IOC bit
+ TBZ(x5, FPSR_IOC, 4+4);
+ MOVw_REG(x1, x2);
+ VMOVQSfrom(q0, i, x1);
+ }
+ }
+ break;
+ case 0x2D:
+ INST_NAME("CVTPD2PI Gm,Ex");
+ nextop = F8;
+ GETGM(q0);
+ GETEX(v1, 0, 0);
+ if(box64_dynarec_fastround) {
+ u8 = sse_setround(dyn, ninst, x1, x2, x3);
+ VFRINTIDQ(q0, v1);
+ FCVTXN(q0, q0);
+ x87_restoreround(dyn, ninst, u8);
+ VFCVTZSS(q0, q0);
+ } else {
+ u8 = sse_setround(dyn, ninst, x1, x2, x3);
+ MRS_fpsr(x5);
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ MSR_fpsr(x5);
+ ORRw_mask(x2, xZR, 1, 0); //0x80000000
+ d0 = fpu_get_scratch(dyn);
+ for (int i=0; i<2; ++i) {
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ if (i) {
+ VMOVeD(d0, 0, v1, i);
+ FRINTID(d0, d0);
+ } else {
+ FRINTID(d0, v1);
+ }
+ FCVTZSwD(x1, d0);
+ MRS_fpsr(x5); // get back FPSR to check the IOC bit
+ TBZ(x5, FPSR_IOC, 4+4);
+ MOVw_REG(x1, x2);
+ VMOVQSfrom(q0, i, x1);
+ }
+ x87_restoreround(dyn, ninst, u8);
+ }
+ break;
case 0x2E:
// no special check...
case 0x2F:
@@ -241,7 +329,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEX(q1, 0, 0);
VADDPQ_32(q0, q0, q1);
break;
-
+ case 0x03:
+ INST_NAME("PHADDSW Gx, Ex");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1Q_16(v0, q0, q1);
+ VUZP2Q_16(q0, q0, q1);
+ SQADDQ_16(q0, q0, v0);
+ break;
case 0x04:
INST_NAME("PMADDUBSW Gx,Ex");
nextop = F8;
@@ -443,14 +540,14 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x20:
INST_NAME("PMOVSXBW Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
SXTL_8(q0, q1); // 8bits->16bits
break;
case 0x21:
INST_NAME("PMOVSXBD Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX32(q1, 0, 0);
GETGX_empty(q0);
SXTL_8(q0, q1); // 8bits->16bits
SXTL_16(q0, q0); //16bits->32bits
@@ -458,7 +555,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x22:
INST_NAME("PMOVSXBQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX16(q1, 0, 0);
GETGX_empty(q0);
SXTL_8(q0, q1); // 8bits->16bits
SXTL_16(q0, q0); //16bits->32bits
@@ -467,14 +564,14 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x23:
INST_NAME("PMOVSXWD Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
SXTL_16(q0, q1); // 16bits->32bits
break;
case 0x24:
INST_NAME("PMOVSXWQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX32(q1, 0, 0);
GETGX_empty(q0);
SXTL_16(q0, q1); // 16bits->32bits
SXTL_32(q0, q0); // 32bits->64bits
@@ -482,7 +579,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x25:
INST_NAME("PMOVSXDQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
SXTL_32(q0, q1); // 32bits->64bits
break;
@@ -539,14 +636,14 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x30:
INST_NAME("PMOVZXBW Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
UXTL_8(q0, q1); // 8bits->16bits
break;
case 0x31:
INST_NAME("PMOVZXBD Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX32(q1, 0, 0);
GETGX_empty(q0);
UXTL_8(q0, q1); // 8bits->16bits
UXTL_16(q0, q0); //16bits->32bits
@@ -554,7 +651,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x32:
INST_NAME("PMOVZXBQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX16(q1, 0, 0);
GETGX_empty(q0);
UXTL_8(q0, q1); // 8bits->16bits
UXTL_16(q0, q0); //16bits->32bits
@@ -563,14 +660,14 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x33:
INST_NAME("PMOVZXWD Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
UXTL_16(q0, q1); // 16bits->32bits
break;
case 0x34:
INST_NAME("PMOVZXWQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX32(q1, 0, 0);
GETGX_empty(q0);
UXTL_16(q0, q1); // 16bits->32bits
UXTL_32(q0, q0); // 32bits->64bits
@@ -578,11 +675,18 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x35:
INST_NAME("PMOVZXDQ Gx, Ex"); // SSE4 opcode!
nextop = F8;
- GETEX(q1, 0, 0);
+ GETEX64(q1, 0, 0);
GETGX_empty(q0);
UXTL_32(q0, q1); // 32bits->64bits
break;
+ case 0x37:
+ INST_NAME("PCMPGTQ Gx, Ex"); // SSE4 opcode!
+ nextop = F8;
+ GETEX(q1, 0, 0);
+ GETGX(q0, 1);
+ VCMGTQ_64(q0, q0, q1);
+ break;
case 0x38:
INST_NAME("PMINSB Gx, Ex"); // SSE4 opcode!
nextop = F8;
@@ -757,7 +861,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(gd, x1, 0, 16);
} else {
SMREAD();
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, (1<<1)-1, rex, NULL, 0, 0);
LDH(x1, ed, fixedaddress);
REV16x(x1, x1);
BFIx(gd, x1, 0, 16);
@@ -773,7 +877,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, x1, 0, 16);
} else {
SMREAD();
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, (1<<1)-1, rex, NULL, 0, 0);
REV16x(x1, gd);
STH(x1, ed, fixedaddress);
}
@@ -863,7 +967,20 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VMOVeS(q0, i, q1, i);
}
break;
-
+ case 0x0D:
+ INST_NAME("PBLENDPD Gx, Ex, Ib");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 1);
+ u8 = F8&0b11;
+ if(u8==0b01) {
+ VMOVeD(q0, 0, q1, 0);
+ } else if(u8==0b10) {
+ VMOVeD(q0, 1, q1, 1);
+ } else if(u8==0b11) {
+ VMOVQ(q0, q1);
+ }
+ break;
case 0x0E:
INST_NAME("PBLENDW Gx, Ex, Ib");
nextop = F8;
@@ -907,7 +1024,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEX(q1, 0, 1);
u8 = F8;
if(u8>31) {
- VEORQ(q0, q0, q0);
+ VEORQ(q0, q0, q0);
} else if(u8>15) {
d0 = fpu_get_scratch(dyn);
VEORQ(d0, d0, d0);
@@ -970,7 +1087,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SMWRITE2();
}
break;
-
+ case 0x17:
+ INST_NAME("EXTRACTPS Ew, Gx, Ib");
+ nextop = F8;
+ GETGX(q0, 0);
+ if (MODREG) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ u8 = F8&0b11;
+ MOVx_REG(ed, xZR);
+ VMOVSto(ed, q0, u8);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0xfff<<2, 3, rex, NULL, 0, 1);
+ u8 = F8&0b11;
+ VMOVSto(x1, q0, u8);
+ STW(x1, wback, fixedaddress);
+ }
+ break;
case 0x20:
INST_NAME("PINSRB Gx, ED, Ib");
nextop = F8;
@@ -979,7 +1111,30 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
u8 = F8;
VMOVQBfrom(q0, (u8&15), ed);
break;
-
+ case 0x21:
+ INST_NAME("INSERTPS Gx, Ex, Ib");
+ nextop = F8;
+ GETGX(q0, 1);
+ d0 = fpu_get_scratch(dyn);
+ VMOVQ(d0, q0);
+ if (MODREG) {
+ q1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
+ u8 = F8;
+ VMOVeS(q0, (u8>>4)&3, q1, (u8>>6)&3);
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 1);
+ u8 = F8;
+ LDW(x2, wback, fixedaddress);
+ VMOVQSfrom(q0, (u8>>4)&3, x2);
+ }
+ uint8_t zmask = u8 & 0xf;
+ for (uint8_t i=0; i<4; i++) {
+ if (zmask & (1<<i)) {
+ VMOVQSfrom(q0, i, wZR);
+ }
+ }
+ break;
case 0x22:
INST_NAME("PINSRD Gx, ED, Ib");
nextop = F8;
@@ -993,6 +1148,28 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
break;
+ case 0x40:
+ INST_NAME("DPPS Gx, Ex, Ib");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 1);
+ u8 = F8;
+ v0 = fpu_get_scratch(dyn);
+ VFMULQS(v0, q0, q1);
+ // mask some, duplicate all, mask some
+ for(int i=0; i<4; ++i)
+ if(!(u8&(1<<(4+i)))) {
+ VMOVQSfrom(v0, i, xZR);
+ }
+ VFADDPQS(v0, v0, v0);
+ FADDPS(v0, v0);
+ VDUPQ_32(q0, v0, 0);
+ for(int i=0; i<4; ++i)
+ if(!(u8&(1<<i))) {
+ VMOVQSfrom(q0, i, xZR);
+ }
+ break;
+
case 0x44:
INST_NAME("PCLMULQDQ Gx, Ex, Ib");
nextop = F8;
@@ -1021,7 +1198,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
sse_forget_reg(dyn, ninst, gd);
MOV32w(x1, gd); // gx
if(MODREG) {
- ed = (nextop&7)+(rex.b<<3);
+ ed = (nextop&7)+(rex.b<<3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x2, ed);
MOV32w(x3, 0); //p = NULL
@@ -1038,6 +1215,181 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
break;
+ case 0x60:
+ INST_NAME("PCMPESTRM Gx, Ex, Ib");
+ SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);
+ nextop = F8;
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x3, xEmu, offsetof(x64emu_t, xmm[gd]));
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+ if(ed!=x1) {
+ MOVx_REG(x1, ed);
+ }
+ }
+ MOVx_REG(x2, xRDX);
+ MOVx_REG(x4, xRAX);
+ u8 = F8;
+ MOV32w(x5, u8);
+ CALL(sse42_compare_string_explicit_len, x1);
+ q0 = sse_get_reg_empty(dyn, ninst, x2, gd);
+ q1 = fpu_get_scratch(dyn);
+ if(u8&0b1000000) {
+ switch(u8&1) {
+ case 0b00:
+ VDUPQB(q0, x1); // load the low 8bits of the mask
+ LSRw_IMM(x1, x1, 8);
+ VDUPQB(q1, x1); // load the high 8bits of the mask
+ VEXTQ_8(q0, q0, q1, 8); // low and hig bits mask
+ TABLE64(x2, (uintptr_t)&mask_string8);
+ VLDR64_U12(q1, x2, 0); // load shift
+ VDUPQ_64(q1, q1, 0);
+ USHLQ_8(q0, q0, q1); // extract 1 bit
+ MOVIQ_8(q1, 0x80); // load mask
+ VANDQ(q0, q0, q1);
+ VSSHRQ_8(q0, q0, 7); // saturate the mask
+ break;
+ case 0b01:
+ VDUPQH(q0, x1); // load the 8bits of the mask
+ TABLE64(x2, (uintptr_t)&mask_string16);
+ VLDR64_U12(q1, x2, 0); // load shift
+ UXTL_8(q1, q1); // extend mask to 16bits
+ USHLQ_16(q0, q0, q1); // extract 1 bit
+ MOVIQ_16(q1, 0x80, 1); // load mask
+ VANDQ(q0, q0, q1);
+ VSSHRQ_16(q0, q0, 15); // saturate the mask
+ }
+ } else {
+ VEORQ(q0, q0, q0);
+ VMOVQHfrom(q0, 0, x1);
+ }
+ break;
+ case 0x61:
+ INST_NAME("PCMPESTRI Gx, Ex, Ib");
+ SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);
+ nextop = F8;
+ GETG;
+ sse_reflect_reg(dyn, ninst, gd);
+ ADDx_U12(x3, xEmu, offsetof(x64emu_t, xmm[gd]));
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+ if(ed!=x1) {
+ MOVx_REG(x1, ed);
+ }
+ }
+ MOVx_REG(x2, xRDX);
+ MOVx_REG(x4, xRAX);
+ u8 = F8;
+ MOV32w(x5, u8);
+ CALL(sse42_compare_string_explicit_len, x1);
+ CBNZw_MARK(x1);
+ MOV32w(xRCX, (u8&1)?8:16);
+ B_NEXT_nocond;
+ MARK;
+ if(u8&0b1000000) {
+ CLZw(xRCX, x1);
+ MOV32w(x2, 31);
+ SUBw_REG(xRCX, x2, xRCX);
+ } else {
+ RBITxw(xRCX, x1);
+ CLZw(xRCX, xRCX);
+ }
+ break;
+ case 0x62:
+ INST_NAME("PCMPISTRM Gx, Ex, Ib");
+ SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);
+ nextop = F8;
+ GETG;
+ sse_forget_reg(dyn, ninst, gd);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+ if(ed!=x1) {
+ MOVx_REG(x1, ed);
+ }
+ }
+ u8 = F8;
+ MOV32w(x3, u8);
+ CALL(sse42_compare_string_implicit_len, x1);
+ q0 = sse_get_reg_empty(dyn, ninst, x2, gd);
+ q1 = fpu_get_scratch(dyn);
+ if(u8&0b1000000) {
+ switch(u8&1) {
+ case 0b00:
+ VDUPQB(q0, x1); // load the low 8bits of the mask
+ LSRw_IMM(x1, x1, 8);
+ VDUPQB(q1, x1); // load the high 8bits of the mask
+ VEXTQ_8(q0, q0, q1, 8); // low and hig bits mask
+ TABLE64(x2, (uintptr_t)&mask_string8);
+ VLDR64_U12(q1, x2, 0); // load shift
+ VDUPQ_64(q1, q1, 0);
+ USHLQ_8(q0, q0, q1); // extract 1 bit
+ MOVIQ_8(q1, 0x80); // load mask
+ VANDQ(q0, q0, q1);
+ VSSHRQ_8(q0, q0, 7); // saturate the mask
+ break;
+ case 0b01:
+ VDUPQH(q0, x1); // load the 8bits of the mask
+ TABLE64(x2, (uintptr_t)&mask_string16);
+ VLDR64_U12(q1, x2, 0); // load shift
+ UXTL_8(q1, q1); // extend mask to 16bits
+ USHLQ_16(q0, q0, q1); // extract 1 bit
+ MOVIQ_16(q1, 0x80, 1); // load mask
+ VANDQ(q0, q0, q1);
+ VSSHRQ_16(q0, q0, 15); // saturate the mask
+ }
+ } else {
+ VEORQ(q0, q0, q0);
+ VMOVQHfrom(q0, 0, x1);
+ }
+ break;
+ case 0x63:
+ INST_NAME("PCMPISTRI Gx, Ex, Ib");
+ SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET);
+ nextop = F8;
+ GETG;
+ sse_reflect_reg(dyn, ninst, gd);
+ ADDx_U12(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
+ if(MODREG) {
+ ed = (nextop&7)+(rex.b<<3);
+ sse_reflect_reg(dyn, ninst, ed);
+ ADDx_U12(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+ if(ed!=x1) {
+ MOVx_REG(x1, ed);
+ }
+ }
+ u8 = F8;
+ MOV32w(x3, u8);
+ CALL(sse42_compare_string_implicit_len, x1);
+ CBNZw_MARK(x1);
+ MOV32w(xRCX, (u8&1)?8:16);
+ B_NEXT_nocond;
+ MARK;
+ if(u8&0b1000000) {
+ CLZw(xRCX, x1);
+ MOV32w(x2, 31);
+ SUBw_REG(xRCX, x2, xRCX);
+ } else {
+ RBITxw(xRCX, x1);
+ CLZw(xRCX, xRCX);
+ }
+ break;
+
case 0xDF:
INST_NAME("AESKEYGENASSIST Gx, Ex, Ib"); // AES-NI
nextop = F8;
@@ -1045,7 +1397,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
sse_forget_reg(dyn, ninst, gd);
MOV32w(x1, gd); // gx
if(MODREG) {
- ed = (nextop&7)+(rex.b<<3);
+ ed = (nextop&7)+(rex.b<<3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x2, ed);
MOV32w(x3, 0); //p = NULL
@@ -1095,7 +1447,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
LSRx(x1, x1, 63);
LSRx(gd, gd, 63);
BFIx(gd, x1, 1, 1);
- break;
+ break;
case 0x51:
INST_NAME("SQRTPD Gx, Ex");
nextop = F8;
@@ -1115,7 +1467,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VFSQRTQD(q1, q0);
}
break;
-
+
case 0x54:
INST_NAME("ANDPD Gx, Ex");
nextop = F8;
@@ -1140,9 +1492,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0x57:
INST_NAME("XORPD Gx, Ex");
nextop = F8;
- GETEX(q0, 0, 0);
- GETGX(v0, 1);
- VEORQ(v0, v0, q0);
+ GETG;
+ if(MODREG && ((nextop&7)+(rex.b<<3)==gd)) {
+ // special case for XORPD Gx, Gx
+ q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
+ VEORQ(q0, q0, q0);
+ } else {
+ q0 = sse_get_reg(dyn, ninst, x1, gd, 1);
+ GETEX(q1, 0, 0);
+ VEORQ(q0, q0, q1);
+ }
break;
case 0x58:
INST_NAME("ADDPD Gx, Ex");
@@ -1470,32 +1829,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
} else if(u8==0x00) {
// duplicate lower 32bits to all spot
- if(v0!=v1) {
- VMOVeS(v0, 0, v1, 0);
- }
- VMOVeS(v0, 1, v1, 0);
- VMOVeD(v0, 1, v0, 0);
+ VDUPQ_32(v0, v1, 0);
} else if(u8==0x55) {
// duplicate slot 1 to all spot
- if(v0!=v1) {
- VMOVeS(v0, 1, v1, 1);
- }
- VMOVeS(v0, 0, v1, 1);
- VMOVeD(v0, 1, v0, 0);
+ VDUPQ_32(v0, v1, 1);
} else if(u8==0xAA) {
// duplicate slot 2 to all spot
- if(v0!=v1) {
- VMOVeS(v0, 2, v1, 2);
- }
- VMOVeS(v0, 3, v1, 2);
- VMOVeD(v0, 0, v0, 1);
+ VDUPQ_32(v0, v1, 2);
} else if(u8==0xFF) {
// duplicate slot 3 to all spot
- if(v0!=v1) {
- VMOVeS(v0, 3, v1, 3);
- }
- VMOVeS(v0, 2, v1, 3);
- VMOVeD(v0, 0, v0, 1);
+ VDUPQ_32(v0, v1, 3);
+ } else if(u8==0x44) {
+ // duplicate slot 0/1 to all spot
+ VDUPQ_64(v0, v1, 0);
+ } else if(u8==0xEE) {
+ // duplicate slot 2/3 to all spot
+ VDUPQ_64(v0, v1, 1);
+ } else if(u8==0xB1) {
+ // invert 0/1 and 2/3
+ VREV64Q_32(v0, v1);
} else if(v0!=v1) {
VMOVeS(v0, 0, v1, (u8>>(0*2))&3);
VMOVeS(v0, 1, v1, (u8>>(1*2))&3);
@@ -1736,7 +2088,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VORRQ(q1, q1, v1); // NAN -> -NAN
}
break;
-
+ case 0x7D:
+ INST_NAME("HSUBPD Gx, Ex"); // SSE4 opcode!
+ nextop = F8;
+ GETEX(q1, 0, 0);
+ GETGX(q0, 1);
+ v0 = fpu_get_scratch(dyn);
+ VUZP1Q_64(v0, q0, q1);
+ VUZP2Q_64(q0, q0, q1);
+ VFSUBQD(q0, v0, q0);
+ break;
case 0x7E:
INST_NAME("MOVD Ed,Gx");
nextop = F8;
@@ -1796,24 +2157,31 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIw(xFlags, x1, F_CF, 1);
break;
case 0xA4:
+ INST_NAME("SHLD Ew, Gw, Ib");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ nextop = F8;
+ GETEW(x1, 1);
+ GETGW(x2);
+ u8 = F8;
+ emit_shld16c(dyn, ninst, ed, gd, u8, x4, x5);
+ EWBACK;
+ break;
case 0xA5:
nextop = F8;
- if(opcode==0xA4) {
- INST_NAME("SHLD Ew, Gw, Ib");
- } else {
- INST_NAME("SHLD Ew, Gw, CL");
- UXTBw(x3, xRCX);
- }
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_ALL, SF_SET);
- GETEWW(x4, x1, (opcode==0xA4)?1:0);
+ INST_NAME("SHLD Ew, Gw, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
GETGW(x2);
- if(opcode==0xA4) {
- u8 = F8;
- MOV32w(x3, u8);
+ GETEW(x1, 0);
+ UFLAG_IF {
+ ANDSw_mask(x4, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ } else {
+ ANDw_mask(x4, xRCX, 0, 0b00100); //mask=0x00000001f
}
- CALL_(shld16, x1, wback);
- EWBACKW(x1);
+ emit_shld16(dyn, ninst, ed, gd, x4, x5, x6);
+ EWBACK;
break;
case 0xAB:
@@ -1834,48 +2202,55 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
ed = x4;
}
ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f
- LSRw_REG(x1, ed, x2);
- BFIw(xFlags, x1, F_CF, 1);
- ANDSw_mask(x1, x1, 0, 0); //mask=1
- B_NEXT(cNE);
+ IFX(X_CF) {
+ LSRw_REG(x1, ed, x2);
+ BFIw(xFlags, x1, F_CF, 1);
+ }
MOV32w(x1, 1);
- LSLxw_REG(x1, x1, x2);
+ LSLw_REG(x1, x1, x2);
ORRx_REG(ed, ed, x1);
if(wback) {
STRH_U12(ed, wback, fixedaddress);
}
break;
case 0xAC:
+ nextop = F8;
+ INST_NAME("SHRD Ew, Gw, Ib");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ GETEW(x1, 1);
+ GETGW(x2);
+ u8 = F8;
+ emit_shrd16c(dyn, ninst, ed, gd, u8, x4, x5);
+ EWBACK;
+ break;
case 0xAD:
nextop = F8;
- if(opcode==0xAC) {
- INST_NAME("SHRD Ew, Gw, Ib");
- } else {
- INST_NAME("SHRD Ew, Gw, CL");
- UXTBw(x3, xRCX);
- }
- MESSAGE(LOG_DUMP, "Need Optimization\n");
- SETFLAGS(X_ALL, SF_SET);
- GETEWW(x4, x1, (opcode==0xAC)?1:0);
+ INST_NAME("SHRD Ew, Gw, CL");
+ SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+ if(box64_dynarec_safeflags>1)
+ MAYSETFLAGS();
GETGW(x2);
- if(opcode==0xAC) {
- u8 = F8;
- MOV32w(x3, u8);
+ GETEW(x1, 0);
+ UFLAG_IF {
+ ANDSw_mask(x4, xRCX, 0, 0b00100); //mask=0x00000001f
+ B_NEXT(cEQ);
+ } else {
+ ANDw_mask(x4, xRCX, 0, 0b00100); //mask=0x00000001f
}
- CALL_(shrd16, x1, wback);
- EWBACKW(x1);
+ emit_shrd16(dyn, ninst, ed, gd, x4, x5, x6);
+ EWBACK;
break;
case 0xAF:
INST_NAME("IMUL Gw,Ew");
SETFLAGS(X_ALL, SF_PENDING);
nextop = F8;
- UFLAG_DF(x1, d_imul16);
GETSEW(x1, 0);
GETSGW(x2);
MULw(x2, x2, x1);
UFLAG_RES(x2);
GWBACK;
+ UFLAG_DF(x1, d_imul16);
break;
case 0xB3:
@@ -1899,8 +2274,6 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f
LSRw_REG(x1, ed, x2);
BFIw(xFlags, x1, F_CF, 1);
- ANDSw_mask(x1, x1, 0, 0); //mask=1
- B_NEXT(cEQ);
MOV32w(x1, 1);
LSLxw_REG(x1, x1, x2);
BICx_REG(ed, ed, x1);
@@ -1916,7 +2289,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(MODREG) {
if(rex.rex) {
eb1 = xRAX+(nextop&7)+(rex.b<<3);
- eb2 = 0; \
+ eb2 = 0;
} else {
ed = (nextop&7);
eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
@@ -1967,12 +2340,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEW(x1, 1);
u8 = F8;
u8&=(rex.w?0x3f:0x0f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
- TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
MOV32w(x4, 1);
- ORRxw_REG_LSL(ed, ed, x4, u8);
+ BFIxw(ed, x4, u8, 1);
EWBACK(x1);
- MARK3;
break;
case 6:
INST_NAME("BTR Ew, Ib");
@@ -1981,12 +2354,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEW(x1, 1);
u8 = F8;
u8&=(rex.w?0x3f:0x0f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
- TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction
- MOV32w(x4, 1);
- BICxw_REG_LSL(ed, ed, x4, u8);
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
+ BFCxw(ed, u8, 1);
EWBACK(x1);
- MARK3;
break;
case 7:
INST_NAME("BTC Ew, Ib");
@@ -1995,7 +2367,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETEW(x1, 1);
u8 = F8;
u8&=(rex.w?0x3f:0x0f);
- BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ IFX(X_CF) {
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
EWBACK(x1);
@@ -2023,9 +2397,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
ed = x4;
}
ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f
- LSRw_REG(x1, ed, x2);
- BFIw(xFlags, x1, F_CF, 1);
- ANDw_mask(x1, x1, 0, 0); //mask=1
+ IFX(X_CF) {
+ LSRw_REG(x1, ed, x2);
+ BFIw(xFlags, x1, F_CF, 1);
+ }
MOV32w(x1, 1);
LSLxw_REG(x1, x1, x2);
EORx_REG(ed, ed, x1);
@@ -2091,6 +2466,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(gd, x1, 0, 16);
break;
+ case 0xC1:
+ INST_NAME("XADD Gw, Ew");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ nextop = F8;
+ GETGW(x1);
+ GETEW(x2, 0);
+ BFIx(xRAX+((nextop&0x38)>>3)+(rex.r<<3), ed, 0, 16);
+ emit_add16(dyn, ninst, ed, gd, x4, x5);
+ EWBACK;
+ break;
case 0xC2:
INST_NAME("CMPPD Gx, Ex, Ib");
nextop = F8;
@@ -2102,21 +2487,21 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0: VFCMEQQD(v0, v0, v1); break; // Equal
case 1: VFCMGTQD(v0, v1, v0); break; // Less than
case 2: VFCMGEQD(v0, v1, v0); break; // Less or equal
- case 3: VFCMEQQD(v0, v0, v0);
+ case 3: VFCMEQQD(v0, v0, v0);
if(v0!=v1) {
- q0 = fpu_get_scratch(dyn);
- VFCMEQQD(q0, v1, v1);
+ q0 = fpu_get_scratch(dyn);
+ VFCMEQQD(q0, v1, v1);
VANDQ(v0, v0, q0);
}
- VMVNQ(v0, v0);
+ VMVNQ(v0, v0);
break; // NaN (NaN is not equal to himself)
case 4: VFCMEQQD(v0, v0, v1); VMVNQ(v0, v0); break; // Not Equal (or unordered on ARM, not on X86...)
case 5: VFCMGTQD(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or equal or unordered
case 6: VFCMGEQD(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or unordered
- case 7: VFCMEQQD(v0, v0, v0);
+ case 7: VFCMEQQD(v0, v0, v0);
if(v0!=v1) {
- q0 = fpu_get_scratch(dyn);
- VFCMEQQD(q0, v1, v1);
+ q0 = fpu_get_scratch(dyn);
+ VFCMEQQD(q0, v1, v1);
VANDQ(v0, v0, q0);
}
break; // not NaN
@@ -2206,6 +2591,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VDUPQ_16(v0, v0, 0); // only the low 8bits will be used anyway
USHLQ_16(q0, q0, v0); // SHR x8
break;
+ case 0xD0:
+ INST_NAME("ADDSUBPD Gx,Ex");
+ nextop = F8;
+ GETGX(q0, 1);
+ GETEX(q1, 0, 0);
+ v0 = fpu_get_scratch(dyn);
+ VFSUBQD(v0, q0, q1);
+ VFADDQD(q0, q0, q1);
+ VMOVeD(q0, 0, v0, 0);
+ break;
case 0xD2:
INST_NAME("PSRLD Gx,Ex");
nextop = F8;
@@ -2283,7 +2678,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
UADDLV_8(q1, q1); // accumalte
VMOVBto(x1, q1, 0);
BFIx(gd, x1, 8, 8);
- break;
+ break;
case 0xD8:
INST_NAME("PSUBUSB Gx, Ex");
nextop = F8;
diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c
index fe32cf9..f26a17c 100644
--- a/src/dynarec/arm64/dynarec_arm64_66f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_66f0.c
@@ -53,7 +53,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGW(x5);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
@@ -61,13 +60,22 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_or16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDSETALH(x5, x1, wback);
+ emit_or16(dyn, ninst, x1, x5, x3, x4);
+ } else {
+ STSETLH(x5, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_or16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 0x0F:
@@ -79,7 +87,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
UXTHw(x6, xRAX);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
@@ -90,34 +97,43 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, gd, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(wback, 1, 0, 0); // mask=1
- B_MARK3(cNE);
+ if(!ALIGNED_ATOMICH) {
+ TSTx_mask(wback, 1, 0, 0); // mask=1
+ B_MARK3(cNE);
+ }
// Aligned version
- MARKLOCK;
- LDAXRH(x1, wback);
- CMPSw_REG(x6, x1);
- B_MARK(cNE);
- // EAX == Ed
- STLXRH(x4, gd, wback);
- CBNZx_MARKLOCK(x4);
- // done
- B_MARK_nocond;
- // Unaligned version
- MARK3;
- LDRH_U12(x1, wback, 0);
- LDAXRB(x3, wback); // dummy read, to arm the write...
- CMPSw_REG(x6, x1);
- B_MARK(cNE);
- // EAX == Ed
- STLXRB(x4, gd, wback);
- CBNZx_MARK3(x4);
- STRH_U12(gd, wback, 0);
+ if(arm64_atomics) {
+ MOVw_REG(x1, x6);
+ CASALH(x1, gd, wback);
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ CMPSw_REG(x6, x1);
+ B_MARK(cNE);
+ // EAX == Ed
+ STLXRH(x4, gd, wback);
+ CBNZx_MARKLOCK(x4);
+ // done
+ }
+ if(!ALIGNED_ATOMICH) {
+ B_MARK_nocond;
+ // Unaligned version
+ MARK3;
+ LDRH_U12(x1, wback, 0);
+ LDAXRB(x3, wback); // dummy read, to arm the write...
+ CMPSw_REG(x6, x1);
+ B_MARK(cNE);
+ // EAX == Ed
+ STLXRB(x4, gd, wback);
+ CBNZx_MARK3(x4);
+ STRH_U12(gd, wback, 0);
+ }
}
+ SMDMB();
MARK;
// Common part (and fallback for EAX != Ed)
UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);}
BFIx(xRAX, x1, 0, 16);
- SMDMB();
break;
case 0xC1:
@@ -126,7 +142,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
nextop = F8;
gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);
UXTHx(x5, gd);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
BFIx(gd, ed, 0, 16);
@@ -134,18 +149,22 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, x5, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRH(x1, wback);
- ADDxw_REG(x4, x1, x5);
- STLXRH(x3, x4, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ LDADDALH(x5, x1, wback);
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ ADDxw_REG(x4, x1, x5);
+ STLXRH(x3, x4, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
IFX(X_ALL|X_PEND) {
MOVxw_REG(x2, x1);
emit_add16(dyn, ninst, x2, x5, x3, x4);
}
BFIx(gd, x1, 0, 16);
}
- SMDMB();
break;
default:
@@ -158,7 +177,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGW(x5);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
@@ -171,13 +189,12 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
emit_adc16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
+ SMDMB();
}
- SMDMB();
break;
case 0x81:
case 0x83:
nextop = F8;
- SMDMB();
switch((nextop>>3)&7) {
case 0: //ADD
if(opcode==0x81) {
@@ -197,22 +214,35 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
- TSTx_mask(wback, 1, 0, 0); // mask=1
- B_MARK(cNE);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_add16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- B_NEXT_nocond;
- MARK; // unaligned! also, not enough
- LDRH_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIw(x1, x4, 0, 8); // re-inject
- emit_add16(dyn, ninst, x1, x5, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARK(x3);
- STRH_U12(x1, wback, 0); // put the whole value
+ if(!ALIGNED_ATOMICH) {
+ TSTx_mask(wback, 1, 0, 0); // mask=1
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ LDADDALH(x5, x1, wback);
+ UFLAG_IF {
+ emit_add16(dyn, ninst, x1, x5, x3, x4);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_add16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
+ if(!ALIGNED_ATOMICH) {
+ B_NEXT_nocond;
+ MARK; // unaligned! also, not enough
+ LDRH_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIw(x1, x4, 0, 8); // re-inject
+ emit_add16(dyn, ninst, x1, x5, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARK(x3);
+ STRH_U12(x1, wback, 0); // put the whole value
+ SMDMB();
+ }
}
break;
case 1: //OR
@@ -229,11 +259,21 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_or16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDSETALH(x5, x1, wback);
+ emit_or16(dyn, ninst, x1, x5, x3, x4);
+ } else {
+ STSETLH(x5, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_or16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 2: //ADC
@@ -256,6 +296,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
emit_adc16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
+ SMDMB();
}
break;
case 3: //SBB
@@ -278,6 +319,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
emit_sbb16(dyn, ninst, x1, x5, x3, x4);
STLXRH(x3, x1, wback);
CBNZx_MARKLOCK(x3);
+ SMDMB();
}
break;
case 4: //AND
@@ -293,12 +335,24 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
- MOV32w(x5, i32);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_and16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x5, ~i32);
+ UFLAG_IF {
+ LDCLRALH(x5, x1, wback);
+ MVNw_REG(x5, x5);
+ emit_and16(dyn, ninst, x1, x5, x3, x4);
+ } else {
+ STCLRLH(x5, wback);
+ }
+ } else {
+ MOV32w(x5, i32);
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_and16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
}
break;
case 5: //SUB
@@ -315,22 +369,38 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
- TSTx_mask(wback, 1, 0, 0); // mask=1
- B_MARK(cNE);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_sub16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- B_NEXT_nocond;
- MARK; // unaligned! also, not enough
- LDRH_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIw(x1, x4, 0, 8); // re-inject
- emit_sub16(dyn, ninst, x1, x5, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARK(x3);
- STRH_U12(x1, wback, 0); // put the whole value
+ if(!ALIGNED_ATOMICH) {
+ TSTx_mask(wback, 1, 0, 0); // mask=1
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ NEGw_REG(x4, x5);
+ UFLAG_IF {
+ LDADDALH(x4, x1, wback);
+ emit_sub16(dyn, ninst, x1, x5, x3, x4);
+ } else {
+ STADDLH(x4, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_sub16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
+ if(!ALIGNED_ATOMICH) {
+ B_NEXT_nocond;
+ MARK; // unaligned! also, not enough
+ LDRH_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIw(x1, x4, 0, 8); // re-inject
+ emit_sub16(dyn, ninst, x1, x5, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARK(x3);
+ STRH_U12(x1, wback, 0); // put the whole value
+ SMDMB();
+ }
}
break;
case 6: //XOR
@@ -347,11 +417,21 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
if(opcode==0x81) i32 = F16S; else i32 = F8S;
MOV32w(x5, i32);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_xor16(dyn, ninst, x1, x5, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDEORALH(x5, x1, wback);
+ emit_xor16(dyn, ninst, x1, x5, x3, x4);
+ } else {
+ STEORLH(x5, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_xor16(dyn, ninst, x1, x5, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
}
break;
case 7: //CMP
@@ -369,7 +449,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
break;
}
- SMDMB();
break;
case 0xFF:
@@ -379,7 +458,6 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0: // INC Ew
INST_NAME("LOCK INC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
@@ -387,18 +465,27 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_inc16(dyn, ninst, x1, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x3, 1);
+ UFLAG_IF {
+ LDADDALH(x3, x1, wback);
+ emit_inc16(dyn, ninst, x1, x3, x4);
+ } else {
+ STADDLH(x3, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_inc16(dyn, ninst, x1, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 1: //DEC Ew
INST_NAME("LOCK DEC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
@@ -406,13 +493,23 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFIx(ed, x6, 0, 16);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRH(x1, wback);
- emit_dec16(dyn, ninst, x1, x3, x4);
- STLXRH(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x3, -1);
+ UFLAG_IF {
+ LDADDALH(x3, x1, wback);
+ emit_dec16(dyn, ninst, x1, x3, x4);
+ } else {
+ STADDLH(x3, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRH(x1, wback);
+ emit_dec16(dyn, ninst, x1, x3, x4);
+ STLXRH(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
- SMDMB();
break;
default:
DEFAULT;
diff --git a/src/dynarec/arm64/dynarec_arm64_66f20f.c b/src/dynarec/arm64/dynarec_arm64_66f20f.c
new file mode 100644
index 0000000..869cf30
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_66f20f.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_functions.h"
+#include "dynarec_arm64_helper.h"
+#include "emu/x64compstrings.h"
+
+uintptr_t dynarec64_66F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+ (void)ip; (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop, u8;
+ int32_t i32;
+ uint8_t gd, ed;
+ uint8_t wback, wb1, wb2;
+ uint8_t eb1, eb2;
+ int64_t j64;
+ uint64_t tmp64u, tmp64u2;
+ int v0, v1;
+ int q0, q1;
+ int d0, d1;
+ int64_t fixedaddress;
+ int unscaled;
+
+ MAYUSE(d0);
+ MAYUSE(d1);
+ MAYUSE(q0);
+ MAYUSE(q1);
+ MAYUSE(eb1);
+ MAYUSE(eb2);
+ MAYUSE(j64);
+ #if STEP > 1
+ static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
+ static const int8_t mask_string8[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
+ static const int8_t mask_string16[] = { 15, 14, 13, 12, 11, 10, 9, 8 };
+ static const int8_t round_round[] = { 0, 2, 1, 3};
+ #endif
+
+ switch(opcode) {
+
+ case 0x38: // SSE 4.x
+ opcode = F8;
+ switch(opcode) {
+
+ case 0xF1:
+ INST_NAME("CRC32 Gd, Ew");
+ nextop = F8;
+ GETEW(x1, 0);
+ GETGD;
+ if(arm64_crc32) {
+ CRC32CH(gd, gd, ed);
+ } else {
+ MOV32w(x2, 0x82f63b78);
+ for(int j=0; j<2; ++j) {
+ UBFXxw(x3, ed, 8*j, 8);
+ EORw_REG(gd, gd, x3);
+ for(int i=0; i<8; ++i) {
+ LSRw_IMM((i&1)?gd:x4, (i&1)?x4:gd, 1);
+ TBZ((i&1)?x4:gd, 0, 4+4);
+ EORw_REG((i&1)?gd:x4, (i&1)?gd:x4, x2);
+ }
+ }
+ }
+ break;
+
+ default:
+ DEFAULT;
+ }
+ break;
+
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_66f30f.c b/src/dynarec/arm64/dynarec_arm64_66f30f.c
new file mode 100644
index 0000000..11a18eb
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_66f30f.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_functions.h"
+#include "dynarec_arm64_helper.h"
+#include "emu/x64compstrings.h"
+
+uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+ (void)ip; (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop, u8;
+ int32_t i32;
+ uint8_t gd, ed;
+ uint8_t wback, wb1, wb2;
+ uint8_t eb1, eb2;
+ int64_t j64;
+ uint64_t tmp64u, tmp64u2;
+ int v0, v1;
+ int q0, q1;
+ int d0, d1;
+ int64_t fixedaddress;
+ int unscaled;
+
+ MAYUSE(d0);
+ MAYUSE(d1);
+ MAYUSE(q0);
+ MAYUSE(q1);
+ MAYUSE(eb1);
+ MAYUSE(eb2);
+ MAYUSE(j64);
+ #if STEP > 1
+ static const int8_t mask_shift8[] = { -7, -6, -5, -4, -3, -2, -1, 0 };
+ static const int8_t mask_string8[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
+ static const int8_t mask_string16[] = { 15, 14, 13, 12, 11, 10, 9, 8 };
+ static const int8_t round_round[] = { 0, 2, 1, 3};
+ #endif
+
+ switch(opcode) {
+
+
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 06e1e93..7930fda 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -276,7 +276,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(MODREG) {
if(rex.rex) {
eb1 = xRAX+(nextop&7)+(rex.b<<3);
- eb2 = 0; \
+ eb2 = 0;
} else {
ed = (nextop&7);
eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
@@ -761,12 +761,12 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
gb2 = 0;
gb1 = xRAX + gd;
} else {
- gb2 = ((gd&4)>>2);
+ gb2 = ((gd&4)<<1);
gb1 = xRAX+(gd&3);
}
if(gb2) {
gd = x4;
- UBFXw(gd, gb1, gb2*8, 8);
+ UBFXw(gd, gb1, gb2, 8);
} else {
gd = gb1; // no need to extract
}
@@ -798,7 +798,40 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SMWRITELOCK(lock);
}
break;
-
+ case 0x8A:
+ INST_NAME("MOV Gb, Eb");
+ nextop = F8;
+ if(rex.rex) {
+ gb1 = gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3);
+ gb2=0;
+ } else {
+ gd = (nextop&0x38)>>3;
+ gb1 = xRAX+(gd&3);
+ gb2 = ((gd&4)<<1);
+ }
+ if(MODREG) {
+ if(rex.rex) {
+ wback = xRAX+(nextop&7)+(rex.b<<3);
+ wb2 = 0;
+ } else {
+ wback = (nextop&7);
+ wb2 = (wback>>2);
+ wback = xRAX+(wback&3);
+ }
+ if(wb2) {
+ UBFXw(x4, wback, wb2*8, 8);
+ ed = x4;
+ } else {
+ ed = wback;
+ }
+ } else {
+ addr = geted32(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 0);
+ SMREADLOCK(lock);
+ LDB(x4, wback, fixedaddress);
+ ed = x4;
+ }
+ BFIx(gb1, ed, gb2, 8);
+ break;
case 0x8B:
INST_NAME("MOV Gd, Ed");
nextop=F8;
@@ -1008,7 +1041,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -1022,11 +1054,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
- UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@@ -1040,6 +1072,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
+ UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
break;
case 6:
INST_NAME("DIV Ed");
diff --git a/src/dynarec/arm64/dynarec_arm64_6764_32.c b/src/dynarec/arm64/dynarec_arm64_6764_32.c
new file mode 100644
index 0000000..f934218
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_6764_32.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+#define GETGm gd = ((nextop&0x38)>>3)
+
+uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog)
+{
+ (void)ip; (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop;
+ uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
+ int64_t fixedaddress;
+ int unscaled;
+ int8_t i8;
+ uint8_t u8;
+ int32_t i32;
+ int64_t j64, i64;
+ int cacheupd = 0;
+ int lock;
+ int v0, v1, s0;
+ MAYUSE(i32);
+ MAYUSE(j64);
+ MAYUSE(v0);
+ MAYUSE(v1);
+ MAYUSE(s0);
+ MAYUSE(lock);
+ MAYUSE(cacheupd);
+
+ if(!rex.is32bits) {
+ // should do a different file
+ DEFAULT;
+ return addr;
+ }
+
+ rep = 0;
+ while((opcode==0xF2) || (opcode==0xF3)) {
+ rep = opcode-0xF1;
+ opcode = F8;
+ }
+
+ switch(opcode) {
+
+ case 0xA3:
+ INST_NAME("MOV Seg:[Od], EAX");
+ i32 = F16;
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ if(i32<4096 && !(i32&3)) {
+ STRw_U12(xRAX, x4, i32);
+ } else if(i32<256) {
+ STURw_I9(xRAX, x4, i32);
+ } else {
+ MOV32w(x1, i32);
+ STRw_REG(xRAX, x4, x1);
+ }
+ break;
+
+ case 0xFF:
+ nextop = F8;
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ switch((nextop>>3)&7) {
+ case 6: // Push Ed
+ INST_NAME("PUSH FS:Ew");
+ if((nextop&0xC0)==0xC0) { // reg
+ DEFAULT;
+ } else { // mem <= i32
+ SMREAD();
+ addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0, 0, 0);
+ LDRw_REG(x3, ed, x4);
+ PUSH1_32(x3);
+ }
+ break;
+ default:
+ DEFAULT;
+ }
+ break;
+
+
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_67_32.c b/src/dynarec/arm64/dynarec_arm64_67_32.c
new file mode 100644
index 0000000..c431599
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_67_32.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+#define GETGm gd = ((nextop&0x38)>>3)
+
+uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+ (void)ip; (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop;
+ uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
+ int64_t fixedaddress;
+ int unscaled;
+ int8_t i8;
+ uint8_t u8;
+ int32_t i32;
+ int64_t j64, i64;
+ int cacheupd = 0;
+ int lock;
+ int v0, v1, s0;
+ MAYUSE(i32);
+ MAYUSE(j64);
+ MAYUSE(v0);
+ MAYUSE(v1);
+ MAYUSE(s0);
+ MAYUSE(lock);
+ MAYUSE(cacheupd);
+
+ if(!rex.is32bits) {
+ // should do a different file
+ DEFAULT;
+ return addr;
+ }
+
+ rep = 0;
+ while((opcode==0xF2) || (opcode==0xF3)) {
+ rep = opcode-0xF1;
+ opcode = F8;
+ }
+
+ switch(opcode) {
+
+ case 64:
+ addr = dynarec64_6764_32(dyn, addr, ip, ninst, rex, rep, _FS, ok, need_epilog);
+ break;
+
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_d8.c b/src/dynarec/arm64/dynarec_arm64_d8.c
index a363945..0fd7c7c 100644
--- a/src/dynarec/arm64/dynarec_arm64_d8.c
+++ b/src/dynarec/arm64/dynarec_arm64_d8.c
@@ -108,7 +108,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
case 0xE1:
@@ -178,7 +178,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FDIVD(v1, v2, v1);
}
break;
-
+
default:
switch((nextop>>3)&7) {
case 0:
@@ -234,7 +234,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, s0);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, float[ED]");
diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c
index fcb44d1..cf76770 100644
--- a/src/dynarec/arm64/dynarec_arm64_d9.c
+++ b/src/dynarec/arm64/dynarec_arm64_d9.c
@@ -51,7 +51,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xC6:
case 0xC7:
INST_NAME("FLD STx");
- v2 = x87_do_push(dyn, ninst, x1, X87_ST(nextop&7));
+ X87_PUSH_OR_FAIL(v2, dyn, ninst, x1, X87_ST(nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, (nextop&7)+1, X87_COMBINE(0, (nextop&7)+1));
if(ST_IS_F(0)) {
FMOVS(v2, v1);
@@ -84,7 +84,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xD8:
INST_NAME("FSTPNCE ST0, ST0");
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
case 0xDA:
@@ -98,7 +98,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
INST_NAME("FCHS");
@@ -138,7 +138,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xE8:
INST_NAME("FLD1");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
if(ST_IS_F(0)) {
FMOVS_8(v1, 0b01110000);
} else {
@@ -147,82 +147,123 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xE9:
INST_NAME("FLDL2T");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
FTABLE64(v1, L2T);
break;
- case 0xEA:
+ case 0xEA:
INST_NAME("FLDL2E");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
FTABLE64(v1, L2E);
break;
case 0xEB:
INST_NAME("FLDPI");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
FTABLE64(v1, PI);
break;
case 0xEC:
INST_NAME("FLDLG2");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
FTABLE64(v1, LG2);
break;
case 0xED:
INST_NAME("FLDLN2");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
FTABLE64(v1, LN2);
break;
case 0xEE:
INST_NAME("FLDZ");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
VEOR(v1, v1, v1);
break;
case 0xF0:
INST_NAME("F2XM1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_f2xm1, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xF1:
INST_NAME("FYL2X");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fyl2x, -1);
- x87_do_pop(dyn, ninst, x3);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF2:
INST_NAME("FPTAN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_ftan, -1);
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F);
- if(ST_IS_F(0)) {
- FMOVS_8(v1, 0b01110000);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ if(PK(0)==0xdd && PK(1)==0xd8) {
+ MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emiting 1\n");
+ u8 = F8;
+ u8 = F8;
} else {
- FMOVD_8(v1, 0b01110000);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
+ if(ST_IS_F(0)) {
+ FMOVS_8(v1, 0b01110000);
+ } else {
+ FMOVD_8(v1, 0b01110000);
+ }
}
break;
case 0xF3:
INST_NAME("FPATAN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fpatan, -1);
- x87_do_pop(dyn, ninst, x3);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF4:
INST_NAME("FXTRACT");
MESSAGE(LOG_DUMP, "Need Optimization\n");
- x87_do_push_empty(dyn, ninst, 0);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fxtract, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xF5:
INST_NAME("FPREM1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ #if 0
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fprem1, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ #else
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
+ s0 = fpu_get_scratch(dyn);
+ FDIVD(s0, v1, v2);
+ FRINTRRD(s0, s0, 0b00); // Nearest == TieToEven?
+ FCVTZSxD(x4, s0);
+ FMULD(s0, s0, v2);
+ FSUBD(v1, v1, s0);
+ LDRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
+ // set C2 = 0
+ BFCw(x1, 10, 1);
+ // set C1 = Q0
+ BFIw(x1, x4, 9, 1);
+ // set C3 = Q1
+ LSRx_IMM(x4, x4, 1);
+ BFIw(x1, x4, 14, 1);
+ // Set C0 = Q2
+ LSRx(x4, x4, 1);
+ BFIw(x1, x4, 8, 1);
+ STRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
+ #endif
break;
case 0xF6:
INST_NAME("FDECSTP");
@@ -242,18 +283,45 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xF8:
INST_NAME("FPREM");
+ #if 0
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fprem, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ #else
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = x87_get_st(dyn, ninst, x1, x2, 1, NEON_CACHE_ST_D);
+ s0 = fpu_get_scratch(dyn);
+ FDIVD(s0, v1, v2);
+ FRINTZD(s0, s0);
+ FCVTZSxD(x4, s0);
+ FMULD(s0, s0, v2);
+ FSUBD(v1, v1, s0);
+ LDRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
+ // set C2 = 0
+ BFCw(x1, 10, 1);
+ // set C1 = Q0
+ BFIw(x1, x4, 9, 1);
+ // set C3 = Q1
+ LSRx_IMM(x4, x4, 1);
+ BFIw(x1, x4, 14, 1);
+ // Set C0 = Q2
+ LSRx(x4, x4, 1);
+ BFIw(x1, x4, 8, 1);
+ STRw_U12(x1, xEmu, offsetof(x64emu_t, sw));
+ #endif
break;
case 0xF9:
INST_NAME("FYL2XP1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fyl2xp1, -1);
- x87_do_pop(dyn, ninst, x3);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xFA:
INST_NAME("FSQRT");
@@ -267,9 +335,11 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xFB:
INST_NAME("FSINCOS");
MESSAGE(LOG_DUMP, "Need Optimization\n");
- x87_do_push_empty(dyn, ninst, 0);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fsincos, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFC:
INST_NAME("FRNDINT");
@@ -292,21 +362,27 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xFD:
INST_NAME("FSCALE");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fscale, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFE:
INST_NAME("FSIN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_fsin, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
case 0xFF:
INST_NAME("FCOS");
MESSAGE(LOG_DUMP, "Need Optimization\n");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_fcos, -1);
+ x87_unstackcount(dyn, ninst, x1, i1);
break;
@@ -322,12 +398,12 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xEF:
DEFAULT;
break;
-
+
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD ST0, float[ED]");
- v1 = x87_do_push(dyn, ninst, x1, box64_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, box64_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v1, ed, fixedaddress);
if(!ST_IS_F(0)) {
@@ -354,7 +430,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCVT_S_D(v1, v1);
}
VST32(v1, ed, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FLDENV Ed");
diff --git a/src/dynarec/arm64/dynarec_arm64_da.c b/src/dynarec/arm64/dynarec_arm64_da.c
new file mode 100644
index 0000000..e1735b8
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_da.c
@@ -0,0 +1,239 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "emu/x87emu_private.h"
+#include "dynarec_native.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+
+uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+ uint8_t nextop = F8;
+ int64_t j64;
+ uint8_t ed;
+ uint8_t wback;
+ int v1, v2;
+ int d0;
+ int s0;
+ int64_t fixedaddress;
+ int unscaled;
+
+ MAYUSE(s0);
+ MAYUSE(d0);
+ MAYUSE(v2);
+ MAYUSE(v1);
+ MAYUSE(ed);
+ MAYUSE(j64);
+
+ switch(nextop) {
+ case 0xC0:
+ case 0xC1:
+ case 0xC2:
+ case 0xC3:
+ case 0xC4:
+ case 0xC5:
+ case 0xC6:
+ case 0xC7:
+ INST_NAME("FCMOVB ST0, STx");
+ READFLAGS(X_CF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ TSTw_mask(xFlags, 0, 0); //mask=1<<F_CF
+ if(ST_IS_F(0)) {
+ FCSELS(v1, v2, v1, cNE); // F_CF==1
+ } else {
+ FCSELD(v1, v2, v1, cNE); // F_CF==1
+ }
+ break;
+ case 0xC8:
+ case 0xC9:
+ case 0xCA:
+ case 0xCB:
+ case 0xCC:
+ case 0xCD:
+ case 0xCE:
+ case 0xCF:
+ INST_NAME("FCMOVE ST0, STx");
+ READFLAGS(X_ZF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ TSTw_mask(xFlags, 0b011010, 0); //mask=1<<F_ZF
+ if(ST_IS_F(0)) {
+ FCSELS(v1, v2, v1, cNE);
+ } else {
+ FCSELD(v1, v2, v1, cNE); // F_ZF==0
+ }
+ break;
+ case 0xD0:
+ case 0xD1:
+ case 0xD2:
+ case 0xD3:
+ case 0xD4:
+ case 0xD5:
+ case 0xD6:
+ case 0xD7:
+ INST_NAME("FCMOVBE ST0, STx");
+ READFLAGS(X_CF|X_ZF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
+ TSTw_REG(xFlags, x1);
+ if(ST_IS_F(0)) {
+ FCSELS(v1, v2, v1, cNE);
+ } else {
+ FCSELD(v1, v2, v1, cNE); // F_CF==0 & F_ZF==0
+ }
+ break;
+ case 0xD8:
+ case 0xD9:
+ case 0xDA:
+ case 0xDB:
+ case 0xDC:
+ case 0xDD:
+ case 0xDE:
+ case 0xDF:
+ INST_NAME("FCMOVU ST0, STx");
+ READFLAGS(X_PF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ TSTw_mask(xFlags, 0b011110, 0); //mask=1<<F_PF
+ if(ST_IS_F(0)) {
+ FCSELS(v1, v2, v1, cNE);
+ } else {
+ FCSELD(v1, v2, v1, cNE); // F_PF==0
+ }
+ break;
+ case 0xE9:
+ INST_NAME("FUCOMPP ST0, ST1");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, 1, X87_COMBINE(0, nextop&7));
+ if(ST_IS_F(0)) {
+ FCMPS(v1, v2);
+ } else {
+ FCMPD(v1, v2);
+ }
+ FCOM(x1, x2, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
+
+ case 0xE4:
+ case 0xF0:
+ case 0xF1:
+ case 0xF4:
+ case 0xF5:
+ case 0xF6:
+ case 0xF7:
+ case 0xF8:
+ case 0xF9:
+ case 0xFD:
+ DEFAULT;
+ break;
+
+ default:
+ switch((nextop>>3)&7) {
+ case 0:
+ INST_NAME("FIADD ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FADDD(v1, v1, v2);
+ break;
+ case 1:
+ INST_NAME("FIMUL ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FMULD(v1, v1, v2);
+ break;
+ case 2:
+ INST_NAME("FICOM ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FCMPD(v1, v2);
+ FCOM(x1, x2, x3);
+ break;
+ case 3:
+ INST_NAME("FICOMP ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FCMPD(v1, v2);
+ FCOM(x1, x2, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
+ case 4:
+ INST_NAME("FISUB ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FSUBD(v1, v1, v2);
+ break;
+ case 5:
+ INST_NAME("FISUBR ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FSUBD(v1, v2, v1);
+ break;
+ case 6:
+ INST_NAME("FIDIV ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FDIVD(v1, v1, v2);
+ break;
+ case 7:
+ INST_NAME("FIDIVR ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
+ VLD32(v2, ed, fixedaddress);
+ SXTL_32(v2, v2); // i32 -> i64
+ SCVTFDD(v2, v2); // i64 -> double
+ FDIVD(v1, v2, v1);
+ break;
+ }
+ }
+ return addr;
+}
+
diff --git a/src/dynarec/arm64/dynarec_arm64_db.c b/src/dynarec/arm64/dynarec_arm64_db.c
index 8974351..f7cb935 100644
--- a/src/dynarec/arm64/dynarec_arm64_db.c
+++ b/src/dynarec/arm64/dynarec_arm64_db.c
@@ -156,7 +156,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
FCOMI(x1, x2);
break;
- case 0xF0:
+ case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
@@ -188,7 +188,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ed");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0);
VLD32(v1, ed, fixedaddress);
SXTL_32(v1, v1); // i32 -> i64
@@ -218,7 +218,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STW(x5, wback, fixedaddress);
MARK3;
#endif
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ed, ST0");
@@ -273,7 +273,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MARK3;
#endif
x87_restoreround(dyn, ninst, u8);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 5:
INST_NAME("FLD tbyte");
@@ -296,13 +296,13 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STRH_U12(x6, ed, 8);
} else {
if(box64_x87_no80bits) {
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D);
VLDR64_U12(v1, ed, fixedaddress);
} else {
if(ed!=x1) {
MOVx_REG(x1, ed);
}
- x87_do_push_empty(dyn, ninst, x3);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
CALL(native_fld, -1);
}
}
@@ -344,7 +344,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
CMPSw_REG(x3, x4);
B_MARK2(cNE);
// NaN and Infinite
- ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff
+ ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff
TSTx_mask(x1, 1, 0, 0b110011); //0x000fffffffffffffL
ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
ORRx_mask(x4, xZR, 1, 0b10, 0b01); //0xc000000000000000
@@ -372,7 +372,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STRH_U12(x3, wback, 8);
#endif
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
diff --git a/src/dynarec/arm64/dynarec_arm64_dc.c b/src/dynarec/arm64/dynarec_arm64_dc.c
index bd6c98d..67be2c2 100644
--- a/src/dynarec/arm64/dynarec_arm64_dc.c
+++ b/src/dynarec/arm64/dynarec_arm64_dc.c
@@ -106,7 +106,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
case 0xE1:
@@ -158,7 +158,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FDIVD(v1, v2, v1);
}
- break;
+ break;
case 0xF8:
case 0xF9:
case 0xFA:
@@ -211,7 +211,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
VLD64(v2, wback, fixedaddress);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FSUB ST0, double[ED]");
diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c
index b269791..3c6b696 100644
--- a/src/dynarec/arm64/dynarec_arm64_dd.c
+++ b/src/dynarec/arm64/dynarec_arm64_dd.c
@@ -74,7 +74,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xD8:
INST_NAME("FSTP ST0, ST0");
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
case 0xDA:
@@ -88,7 +88,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
@@ -126,7 +126,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
@@ -160,34 +160,38 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD double");
- v1 = x87_do_push(dyn, ninst, x3, NEON_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x3, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, ed, fixedaddress);
break;
case 1:
INST_NAME("FISTTP i64, ST0");
- v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
- s0 = fpu_get_scratch(dyn);
- #if 0
- // those are ARM 8.5 opcode!
- FRINT64ZD(s0, v1);
- FCVTZSxD(x2, s0);
- STRx_U12(x2, ed, fixedaddress);
- #else
- MRS_fpsr(x5);
- BFCw(x5, FPSR_IOC, 1); // reset IOC bit
- MSR_fpsr(x5);
- FRINTRRD(s0, v1, 3);
- FCVTZSxD(x2, s0);
- STx(x2, ed, fixedaddress);
- MRS_fpsr(x5); // get back FPSR to check the IOC bit
- TBZ_MARK3(x5, FPSR_IOC);
- ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
- STx(x5, ed, fixedaddress);
- MARK3;
- #endif
- x87_do_pop(dyn, ninst, x3);
+ if(ST_IS_I64(0)) {
+ VST64(v1, ed, fixedaddress);
+ } else {
+ s0 = fpu_get_scratch(dyn);
+ #if 0
+ // those are ARM 8.5 opcode!
+ FRINT64ZD(s0, v1);
+ FCVTZSxD(x2, s0);
+ STRx_U12(x2, ed, fixedaddress);
+ #else
+ MRS_fpsr(x5);
+ BFCw(x5, FPSR_IOC, 1); // reset IOC bit
+ MSR_fpsr(x5);
+ FRINTRRD(s0, v1, 3);
+ FCVTZSxD(x2, s0);
+ STx(x2, ed, fixedaddress);
+ MRS_fpsr(x5); // get back FPSR to check the IOC bit
+ TBZ_MARK3(x5, FPSR_IOC);
+ ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000
+ STx(x5, ed, fixedaddress);
+ MARK3;
+ #endif
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FST double");
@@ -200,9 +204,9 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VST64(v1, ed, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
- case 4:
+ case 4:
INST_NAME("FRSTOR m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
@@ -210,7 +214,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(native_frstor, -1);
break;
- case 6:
+ case 6:
INST_NAME("FSAVE m108byte");
MESSAGE(LOG_DUMP, "Need Optimization\n");
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
@@ -220,7 +224,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 7:
INST_NAME("FNSTSW m2byte");
- fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
+ //fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
addr = geted(dyn, addr, ninst, nextop, &ed, x4, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
LDRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
@@ -234,6 +238,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ANDw_mask(x2, x2, 0, 2);
}
BFIw(x3, x2, 11, 3); // inject TOP at bit 11 (3 bits)
+ STRH_U12(x3, xEmu, offsetof(x64emu_t, sw));
STH(x3, ed, fixedaddress); // store whole sw flags
break;
default:
diff --git a/src/dynarec/arm64/dynarec_arm64_de.c b/src/dynarec/arm64/dynarec_arm64_de.c
index c045d23..c46b081 100644
--- a/src/dynarec/arm64/dynarec_arm64_de.c
+++ b/src/dynarec/arm64/dynarec_arm64_de.c
@@ -53,7 +53,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FADDD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
case 0xC9:
@@ -71,7 +71,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FMULD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD0:
case 0xD1:
@@ -90,7 +90,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
INST_NAME("FCOMPP ST0, STx");
@@ -102,8 +102,8 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
case 0xE1:
@@ -121,7 +121,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FSUBD(v1, v2, v1);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE8:
case 0xE9:
@@ -139,7 +139,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FSUBD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
case 0xF1:
@@ -157,8 +157,8 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FDIVD(v1, v2, v1);
}
- x87_do_pop(dyn, ninst, x3);
- break;
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
case 0xF8:
case 0xF9:
case 0xFA:
@@ -175,7 +175,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
FDIVD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD8:
case 0xDA:
@@ -233,7 +233,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SCVTFDD(v2, v2);
FCMPD(v1, v2);
FCOM(x1, x2, x3);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FISUB ST0, word[ED]");
diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c
index c1ae66a..b81c412 100644
--- a/src/dynarec/arm64/dynarec_arm64_df.c
+++ b/src/dynarec/arm64/dynarec_arm64_df.c
@@ -34,6 +34,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
int64_t j64;
int64_t fixedaddress;
int unscaled;
+ int i1;
MAYUSE(s0);
MAYUSE(v2);
@@ -51,12 +52,20 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xC7:
INST_NAME("FFREEP STx");
// not handling Tag...
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
INST_NAME("FNSTSW AX");
LDRw_U12(x2, xEmu, offsetof(x64emu_t, top));
+ if(dyn->n.x87stack) {
+ if(dyn->n.x87stack>0) {
+ SUBw_U12(x2, x2, dyn->n.x87stack);
+ } else {
+ ADDw_U12(x2, x2, -dyn->n.x87stack);
+ }
+ ANDw_mask(x2, x2, 0, 2); //mask=7
+ }
LDRH_U12(x1, xEmu, offsetof(x64emu_t, sw));
BFIw(x1, x2, 11, 3); // inject top
STRH_U12(x1, xEmu, offsetof(x64emu_t, sw));
@@ -81,7 +90,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOMI(x1, x2);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
case 0xF1:
@@ -102,7 +111,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
FCMPD(v1, v2);
}
FCOMI(x1, x2);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
@@ -151,7 +160,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ew");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
LDSHw(x1, wback, fixedaddress);
if(ST_IS_F(0)) {
@@ -196,7 +205,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MARK3;
STH(x3, wback, fixedaddress);
#endif
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 2:
INST_NAME("FIST Ew, ST0");
@@ -275,19 +284,19 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MARK3;
STH(x3, wback, fixedaddress);
#endif
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
x87_restoreround(dyn, ninst, u8);
break;
case 4:
INST_NAME("FBLD ST0, tbytes");
- x87_do_push_empty(dyn, ninst, x1);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x1);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(fpu_fbld, -1);
break;
case 5:
INST_NAME("FILD ST0, i64");
- v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_I64);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_I64);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0);
VLD64(v1, wback, fixedaddress);
if(!ST_IS_I64(0)) {
@@ -315,11 +324,13 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 6:
INST_NAME("FBSTP tbytes, ST0");
+ i1 = x87_stackcount(dyn, ninst, x1);
x87_forget(dyn, ninst, x1, x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(fpu_fbst, -1);
- x87_do_pop(dyn, ninst, x3);
+ x87_unstackcount(dyn, ninst, x1, i1);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 7:
INST_NAME("FISTP i64, ST0");
@@ -375,7 +386,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#endif
x87_restoreround(dyn, ninst, u8);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_logic.c b/src/dynarec/arm64/dynarec_arm64_emit_logic.c
index e8af51f..fb3f454 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_logic.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_logic.c
@@ -230,15 +230,7 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- TSTw_REG(s1, s1);
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -261,15 +253,7 @@ void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- TSTw_REG(s1, s1);
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -292,15 +276,7 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- TSTw_REG(s1, s1);
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -323,15 +299,7 @@ void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- TSTw_REG(s1, s1);
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -423,15 +391,7 @@ void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -500,15 +460,7 @@ void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_math.c b/src/dynarec/arm64/dynarec_arm64_emit_math.c
index f391f3a..1248ef6 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_math.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_math.c
@@ -303,15 +303,7 @@ void emit_add8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 7); //mask=0xff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -329,7 +321,7 @@ void emit_add8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
SET_DFNONE(s3);
}
IFX(X_AF | X_OF) {
- if(X_PEND) {} else {MOV32w(s4, c&0xff);}
+ IFX(X_PEND) {} else {MOV32w(s4, c&0xff);}
ORRw_REG(s3, s1, s4); // s3 = op1 | op2
ANDw_REG(s4, s1, s4); // s4 = op1 & op2
}
@@ -355,15 +347,7 @@ void emit_add8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4)
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -407,15 +391,7 @@ void emit_sub8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
}
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 7); //mask=0xff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -465,15 +441,7 @@ void emit_sub8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4, in
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
}
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -516,15 +484,7 @@ void emit_add16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
IFX(X_PEND) {
STRw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -634,15 +594,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
}
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -792,16 +744,7 @@ void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
}
}
-
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 7); //mask=0xff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -838,15 +781,7 @@ void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
}
}
- IFX(X_ZF) {
- TSTw_mask(s1, 0, 0b001111); // mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -906,7 +841,7 @@ void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
IFX(X_PEND) {
- STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_dec8);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s3);
@@ -1162,15 +1097,7 @@ void emit_adc8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
LSRw(s3, s1, 8);
BFIw(xFlags, s3, F_CF, 1);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 7); //mask=0xff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -1224,15 +1151,7 @@ void emit_adc16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
LSRw(s3, s1, 16);
BFIw(xFlags, s3, F_CF, 1);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -1474,15 +1393,7 @@ void emit_sbb8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1
}
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 7); //mask=0xff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -1537,15 +1448,7 @@ void emit_sbb16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1
}
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 15);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -1732,10 +1635,9 @@ void emit_neg8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
IFX(X_AF|X_OF) {
MOVw_REG(s3, s1);
}
+ NEGw_REG(s1, s1);
IFX(X_ZF) {
- NEGSw_REG(s1, s1);
- } else {
- NEGw_REG(s1, s1);
+ ANDSw_mask(s1, s1, 0, 7); // mask 0xff
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 007002f..d69231e 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -70,6 +70,10 @@ void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
CSELw(s4, s4, wZR, cEQ);
BFIw(xFlags, s4, F_OF, 1);
}
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -122,6 +126,10 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
BFCw(xFlags, F_OF, 1);
}
}
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -141,19 +149,17 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
- IFX(X_ALL) {
- CMPSxw_U12(s2, 0); //if(!c)
- IFX(X_PEND) {
- Bcond(cNE, +12);
- STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
- }
- B_NEXT(cEQ);
- }
IFX(X_CF) {
SUBxw_U12(s3, s2, 1);
LSRxw_REG(s3, s1, s3);
BFIw(xFlags, s3, 0, 1);
}
+ IFX(X_OF) {
+ CMPSxw_U12(s2, 1); // if s2==1
+ Bcond(cNE, 4+2*4);
+ LSRxw(s4, s1, rex.w?63:31);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
LSRxw_REG(s1, s1, s2);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
@@ -167,13 +173,10 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
LSRxw(s4, s1, (rex.w)?63:31);
BFIx(xFlags, s4, F_SF, 1);
}
- IFX(X_OF) {
- CMPSxw_U12(s2, 1); // if s2==1
- Bcond(cNE, 4+3*4);
- LSRxw(s4, s1, rex.w?62:30);
- EORw_REG_LSR(s4, s4, s4, 1);
- BFIw(xFlags, s4, F_OF, 1);
- }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -197,8 +200,18 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
return;
}
IFX(X_CF) {
- LSRxw(s3, s1, c-1);
- BFIw(xFlags, s3, 0, 1);
+ if(c==1) {
+ BFIw(xFlags, s1, 0, 1);
+ } else {
+ LSRxw(s3, s1, c-1);
+ BFIw(xFlags, s3, 0, 1);
+ }
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRxw(s4, s1, rex.w?63:31);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
}
LSRxw(s1, s1, c);
IFX(X_PEND) {
@@ -213,13 +226,10 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
LSRxw(s4, s1, (rex.w)?63:31);
BFIx(xFlags, s4, F_SF, 1);
}
- IFX(X_OF) {
- if(c==1) {
- LSRxw(s4, s1, rex.w?62:30);
- EORw_REG_LSR(s4, s4, s4, 1);
- BFIw(xFlags, s4, F_OF, 1);
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
}
- }
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -251,7 +261,7 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_ZF) {
- TSTw_REG(s1, s1);
+ TSTxw_REG(s1, s1);
CSETw(s4, cEQ);
BFIw(xFlags, s4, F_ZF, 1);
}
@@ -259,11 +269,528 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
LSRxw(s4, s1, (rex.w)?63:31);
BFIx(xFlags, s4, F_SF, 1);
}
+ IFX(X_OF)
+ if(c==1) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHL8 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch. s3 can be same as s2
+void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ MAYUSE(s2);
+ int64_t j64;
+ MAYUSE(j64);
+
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shl8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF | X_OF) {
+ MOV32w(s4, 8);
+ SUBw_REG(s4, s4, s2);
+ LSRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, F_CF, 1);
+ }
+ LSLw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 8)
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1); // if s2==1
+ IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 7);}
+ EORw_REG(s4, s3, xFlags); // CF is set if OF is asked
+ CSELw(s4, s4, wZR, cEQ);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shl8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(c<8) {
+ IFX(X_CF|X_OF) {
+ BFXILw(xFlags, s1, 8-c, 1);
+ }
+ LSLw(s1, s1, c);
+
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 8)
+ IFX(X_OF) {
+ if(c==1) {
+ IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 7);}
+ EORw_REG(s4, s3, xFlags); // CF is set if OF is asked
+ BFIw(xFlags, s4, F_OF, 1);
+ } else {
+ BFCw(xFlags, F_OF, 1);
+ }
+ }
+ if(box64_dynarec_test) IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+ } else {
+ IFX(X_CF) {
+ LSLw(s3, s1, c-1);
+ BFXILw(xFlags, s3, 7, 1); // insert F_CF from s3[7:1]
+ }
+ MOVw_REG(s1, xZR);
+ IFX(X_OF) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ IFX(X_SF) {
+ BFCw(xFlags, F_SF, 1);
+ }
+ if(box64_dynarec_test) IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF | X_ZF) {
+ MOV32w(s3, 1);
+ IFX(X_ZF) {
+ BFIw(xFlags, s3, F_ZF, 1);
+ }
+ IFX(X_PF) {
+ BFIw(xFlags, s3, F_PF, 1);
+ }
+ }
+ }
+}
+
+// emit SHR8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
+void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ MAYUSE(s2);
+ int64_t j64;
+ MAYUSE(j64);
+
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shr8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ SUBw_U12(s4, s2, 1);
+ LSRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, 0, 1);
+ }
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1); // if s2==1
+ Bcond(cNE, 4+2*4);
+ LSRw(s4, s1, 7);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ LSRw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 8)
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shr8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ if(c==1) {
+ BFIw(xFlags, s1, 0, 1);
+ } else {
+ LSRw(s3, s1, c-1);
+ BFIw(xFlags, s3, 0, 1);
+ }
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s4, s1, 7);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ }
+ LSRw(s1, s1, c);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 8)
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SAR8 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
+void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_sar8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ SUBw_U12(s4, s2, 1);
+ ASRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, 0, 1);
+ }
+ ASRw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 8)
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1);
+ Bcond(cNE, 4+4);
+ BFCw(xFlags, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SAR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_sar8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(c<8) IFX(X_CF) {
+ ASRw(s3, s1, c-1);
+ BFIw(xFlags, s3, 0, 1);
+ }
+ ASRw(s1, s1, c);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ if(c<8) {
+ COMP_ZFSF(s1, 8)
+ IFX(X_OF)
+ if(c==1) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+ } else {
+ LSRw(s3, s1, 7);
+ BFIw(xFlags, s3, F_CF, 1);
+ BFIw(wFlags, s3, F_SF, 1);
+ EORw_mask(s3, s3, 0, 0); //1
+ BFIw(xFlags, s3, F_ZF, 1);
+ MOV32w(s3, 1);
+ BFIw(xFlags, s3, F_PF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+}
+
+// emit SHL16 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch. s3 can be same as s2
+void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shl16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF | X_OF) {
+ MOV32w(s4, 16);
+ SUBw_REG(s4, s4, s2);
+ LSRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, F_CF, 1);
+ }
+ LSLw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1); // if s2==1
+ IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 15);}
+ EORw_REG(s4, s3, xFlags); // CF is set if OF is asked
+ CSELw(s4, s4, wZR, cEQ);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shl16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(c<16) {
+ IFX(X_CF|X_OF) {
+ LSRw(s3, s1, 16-c);
+ BFIw(xFlags, s3, F_CF, 1);
+ }
+ LSLw(s1, s1, c);
+
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ if(c==1) {
+ IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 15);}
+ EORw_REG(s4, s3, xFlags); // CF is set if OF is asked
+ BFIw(xFlags, s4, F_OF, 1);
+ } else {
+ BFCw(xFlags, F_OF, 1);
+ }
+ }
+ if(box64_dynarec_test) IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+ } else {
+ IFX(X_CF) {
+ LSLw(s3, s1, c-1);
+ BFXILw(xFlags, s3, 15, 1); // insert F_CF from s3[15:1]
+ }
+ MOVw_REG(s1, xZR);
+ IFX(X_OF) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ IFX(X_SF) {
+ BFCw(xFlags, F_SF, 1);
+ }
+ IFX(X_PF | X_ZF) {
+ MOV32w(s3, 1);
+ IFX(X_ZF) {
+ BFIw(xFlags, s3, F_ZF, 1);
+ }
+ IFX(X_PF) {
+ BFIw(xFlags, s3, F_PF, 1);
+ }
+ }
+ }
+}
+
+// emit SHR16 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
+void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shr16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ SUBw_U12(s4, s2, 1);
+ LSRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, 0, 1);
+ }
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1); // if s2==1
+ Bcond(cNE, 4+2*4);
+ LSRw(s4, s1, 15);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ LSRw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shr16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ if(c==1) {
+ BFIw(xFlags, s1, 0, 1);
+ } else {
+ LSRw(s3, s1, c-1);
+ BFIw(xFlags, s3, 0, 1);
+ }
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s4, s1, 15);
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ }
+ LSRw(s1, s1, c);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
}
+// emit SAR16 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
+void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s2, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_sar16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ SUBw_U12(s4, s2, 1);
+ ASRw_REG(s4, s1, s4);
+ BFIw(xFlags, s4, 0, 1);
+ }
+ ASRw_REG(s1, s1, s2);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ CMPSw_U12(s2, 1);
+ Bcond(cNE, 4+4);
+ BFCw(xFlags, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SAR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ if(!c)
+ return;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_sar16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ ASRw(s3, s1, c-1);
+ BFIw(xFlags, s3, 0, 1);
+ }
+ ASRw(s1, s1, c);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF)
+ if(c==1) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ if(box64_dynarec_test)
+ IFX(X_AF) {
+ BFCw(xFlags, F_AF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
// emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
{
@@ -318,8 +845,7 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
- LSRxw(s3, s1, rex.w?63:31);
- BFIw(xFlags, s3, F_CF, 1);
+ BFXILxw(xFlags, s1, rex.w?63:31, 1);
}
IFX(X_OF) {
if(c==1) {
@@ -330,6 +856,130 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
}
}
+// emit ROL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_rol8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(!c) {
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ return;
+ }
+ int rc = 8-(c&7);
+ ORRw_REG_LSL(s1, s1, s1, 8);
+ LSRw(s1, s1, rc);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_CF) {
+ BFIw(xFlags, s1, F_CF, 1);
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ EORw_REG_LSR(s3, s1, s1, 7);
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ }
+}
+
+// emit ROR8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_ror8);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(!c) {
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ return;
+ }
+ ORRw_REG_LSL(s1, s1, s1, 8);
+ LSRw(s1, s1, c&7);
+ IFX(X_PEND) {
+ STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_CF) {
+ BFXILw(xFlags, s1, 7, 1);
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s3, s1, 6);
+ EORw_REG_LSR(s3, s3, s3, 1);
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ }
+}
+
+// emit ROL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_rol16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ int rc = 16-(c&15);
+ ORRw_REG_LSL(s1, s1, s1, 16);
+ LSRw(s1, s1, rc);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_CF) {
+ BFIw(xFlags, s1, F_CF, 1);
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ EORw_REG_LSR(s3, s1, s1, 15);
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ }
+}
+
+// emit ROR16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4)
+{
+ MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_ror16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ ORRw_REG_LSL(s1, s1, s1, 16);
+ LSRw(s1, s1, c&15);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_CF) {
+ BFXILw(xFlags, s1, 15, 1);
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s3, s1, 14);
+ EORw_REG_LSR(s3, s3, s3, 1);
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ }
+}
+
// emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch
void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4)
{
@@ -338,8 +988,7 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
MOV32w(s3, c);
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
- // same flags computation as with shl64/shl32
- SET_DF(s4, rex.w?d_shl64:d_shl32);
+ SET_DF(s4, rex.w?d_shrd64:d_shrd32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
@@ -350,11 +999,15 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
return;
}
IFX(X_CF) {
- LSRxw(s3, s1, c-1);
- BFIw(xFlags, s3, 0, 1);
+ BFXILxw(xFlags, s1, c-1, 1); // set CF
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRxw(s4, s1, rex.w?63:31);
+ BFIw(xFlags, s4, F_OF, 1); // store sign for later use
+ }
}
- LSRxw(s3, s1, c);
- ORRxw_REG_LSL(s1, s3, s2, (rex.w?64:32)-c);
+ EXTRxw(s1, s2, s1, c);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
@@ -369,8 +1022,8 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
}
IFX(X_OF) {
if(c==1) {
- LSRxw(s4, s1, rex.w?62:30);
- EORw_REG_LSR(s4, s4, s4, 1);
+ LSRxw(s4, s1, rex.w?63:31);
+ EORw_REG_LSR(s4, s4, xFlags, F_OF); // set if sign changed
BFIw(xFlags, s4, F_OF, 1);
}
}
@@ -386,8 +1039,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
MOV32w(s3, c);
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
- // same flags computation as with shl64/shl32
- SET_DF(s4, rex.w?d_shl64:d_shl32);
+ SET_DF(s4, rex.w?d_shld64:d_shld32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
@@ -400,12 +1052,113 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
}
return;
}
- IFX(X_CF|X_OF) {
+ IFX(X_CF) {
LSRxw(s3, s1, (rex.w?64:32)-c);
BFIxw(xFlags, s3, F_CF, 1);
}
- LSLxw(s3, s1, c);
- ORRxw_REG_LSR(s1, s3, s2, (rex.w?64:32)-c);
+ IFX(X_OF) {
+ LSRxw(s3, s1, rex.w?63:31);
+ BFIw(xFlags, s3, F_OF, 1); // store current sign for later use
+ }
+ EXTRxw(s1, s1, s2, (rex.w?64:32)-c);
+
+ IFX(X_PEND) {
+ STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_ZF) {
+ TSTxw_REG(s1, s1);
+ CSETw(s4, cEQ);
+ BFIw(xFlags, s4, F_ZF, 1);
+ }
+ IFX(X_SF) {
+ LSRxw(s4, s1, (rex.w)?63:31);
+ BFIx(xFlags, s4, F_SF, 1);
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRxw(s3, s1, rex.w?63:31);
+ EORxw_REG_LSR(s3, s3, xFlags, F_OF); // OF is set if sign changed
+ BFIw(xFlags, s3, F_OF, 1);
+ } else {
+ BFCw(xFlags, F_OF, 1);
+ }
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHRD32 instruction, from s1, fill s2 , shift s5, store result in s1 using s3 and s4 as scratch
+void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRxw_U12(s5, xEmu, offsetof(x64emu_t, op2));
+ // same flags computation as with shl64/shl32
+ SET_DF(s4, rex.w?d_shrd64:d_shrd32);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ IFX(X_CF) {
+ SUBw_U12(s3, s5, 1);
+ LSRxw_REG(s3, s1, s3);
+ BFIw(xFlags, s3, F_CF, 1);
+ }
+ IFX(X_OF) {
+ LSRxw(s4, s1, rex.w?63:31);
+ BFIw(xFlags, s4, F_OF, 1); // store sign fr now
+ }
+ LSRxw_REG(s3, s1, s5);
+ SUBxw_U12(s4, s5, rex.w?64:32);
+ NEGxw_REG(s4, s4);
+ LSLxw_REG(s4, s2, s4);
+ ORRxw_REG(s1, s3, s4);
+ IFX(X_PEND) {
+ STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ IFX(X_ZF) {
+ TSTxw_REG(s1, s1);
+ CSETw(s4, cEQ);
+ BFIw(xFlags, s4, F_ZF, 1);
+ }
+ IFX(X_SF) {
+ LSRxw(s4, s1, (rex.w)?63:31);
+ BFIw(xFlags, s4, F_SF, 1);
+ }
+ IFX(X_OF) {
+ CMPSw_U12(s5, 1);
+ Bcond(cNE, 4+3*4);
+ LSRxw(s4, s1, rex.w?63:31);
+ EORw_REG_LSR(s4, s4, xFlags, F_OF); // Set if sign changed
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRxw_U12(s5, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, rex.w?d_shld64:d_shld32);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ MOV32w(s3, (rex.w?64:32));
+ SUBw_REG(s3, s3, s5);
+ IFX(X_CF) {
+ LSRxw_REG(s4, s1, s3);
+ BFIxw(xFlags, s4, F_CF, 1);
+ }
+ IFX(X_OF) {
+ LSRxw(s4, s1, rex.w?63:31);
+ BFIw(xFlags, s4, F_OF, 1); // store current sign for later use
+ }
+ LSLxw_REG(s4, s1, s5);
+ LSRxw_REG(s3, s2, s3);
+ ORRxw_REG(s1, s3, s4);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
@@ -420,9 +1173,142 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
BFIx(xFlags, s4, F_SF, 1);
}
IFX(X_OF) {
+ CMPSw_U12(s5, 1);
+ Bcond(cNE, 4+3*4);
+ LSRxw(s3, s1, rex.w?63:31);
+ EORxw_REG_LSR(s3, s3, xFlags, F_OF); // OF is set if sign changed
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHRD16 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int s3, int s4)
+{
+ c&=0x1f;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shrd16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(!c) {
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ return;
+ }
+ ORRw_REG_LSL(s1, s1, s2, 16); // create concat first
+ IFX(X_CF) {
+ BFXILw(xFlags, s1, c-1, 1); // set CF
+ }
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s4, s1, 15);
+ BFIw(xFlags, s4, F_OF, 1); // store sign for later use
+ }
+ }
+ RORw(s1, s1, c);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ if(c==1) {
+ LSRw(s4, s1, 15);
+ EORw_REG_LSR(s4, s4, xFlags, F_OF); // set if sign changed
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+// emit SHRD16 instruction, from s1, fill s2 , shift s5, store result in s1 using s3 and s4 as scratch
+void emit_shrd16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s5, xEmu, offsetof(x64emu_t, op2));
+ // same flags computation as with shl64/shl32
+ SET_DF(s4, d_shrd16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ ORRw_REG_LSL(s1, s1, s2, 16); // create concat first
+ IFX(X_CF) {
+ SUBw_U12(s3, s5, 1);
+ LSRw_REG(s3, s1, s3);
+ BFIw(xFlags, s3, F_CF, 1);
+ }
+ IFX(X_OF) {
+ LSRw(s4, s1, 15);
+ BFIw(xFlags, s4, F_OF, 1); // store sign fr now
+ }
+ RORw_REG(s1, s1, s5);
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ CMPSw_U12(s5, 1);
+ Bcond(cNE, 4+3*4);
+ LSRw(s4, s1, 15);
+ EORw_REG_LSR(s4, s4, xFlags, F_OF); // Set if sign changed
+ BFIw(xFlags, s4, F_OF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
+
+void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int s3, int s4)
+{
+ c&=0x1f;
+ IFX(X_PEND) {
+ MOV32w(s3, c);
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shld16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ if(c==0) {
+ IFX(X_OF) {
+ BFCw(xFlags, F_OF, 1);
+ }
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ return;
+ }
+ ORRw_REG_LSL(s1, s1, s2, 16); // create concat first
+ IFX(X_CF) {
+ if(c<16)
+ LSRw(s3, s1, 16-c);
+ else
+ MOVx_REG(s3, s1);
+ BFIw(xFlags, s3, F_CF, 1);
+ }
+ IFX(X_OF) {
+ LSRw(s3, s1, 15);
+ BFIw(xFlags, s3, F_OF, 1); // store current sign for later use
+ }
+ RORw(s1, s1, 32-c);
+
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
if(c==1) {
- UBFXxw(s3, s1, rex.w?63:31, 1);
- EORxw_REG(s3, s3, xFlags); // CF is set if OF is asked
+ LSRw(s3, s1, 15);
+ EORw_REG_LSR(s3, s3, xFlags, F_OF); // OF is set if sign changed
BFIw(xFlags, s3, F_OF, 1);
} else {
BFCw(xFlags, F_OF, 1);
@@ -432,3 +1318,46 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint
emit_pf(dyn, ninst, s1, s3, s4);
}
}
+
+void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, int s4)
+{
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
+ STRH_U12(s5, xEmu, offsetof(x64emu_t, op2));
+ SET_DF(s4, d_shld16);
+ } else IFX(X_ALL) {
+ SET_DFNONE(s4);
+ }
+ ORRw_REG_LSL(s1, s1, s2, 16); // create concat first
+ IFX(X_CF) {
+ MOVw_REG(s3, s1);
+ CMPSw_U12(s5, 16);
+ Bcond(cGE, 4+3*4);
+ MOV32w(s3, 16);
+ SUBw_REG(s3, s3, s5);
+ LSRw_REG(s3, s1, s3);
+ BFIw(xFlags, s3, F_CF, 1);
+ }
+ IFX(X_OF) {
+ LSRw(s3, s1, 15);
+ BFIw(xFlags, s3, F_OF, 1); // store current sign for later use
+ }
+ MOV32w(s3, 32);
+ SUBw_REG(s3, s3, s5);
+ RORw_REG(s1, s1, s3);
+
+ IFX(X_PEND) {
+ STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
+ }
+ COMP_ZFSF(s1, 16)
+ IFX(X_OF) {
+ CMPSw_U12(s5, 1);
+ Bcond(cNE, 4+3*4);
+ LSRw(s3, s1, 15);
+ EORw_REG_LSR(s3, s3, xFlags, F_OF); // OF is set if sign changed
+ BFIw(xFlags, s3, F_OF, 1);
+ }
+ IFX(X_PF) {
+ emit_pf(dyn, ninst, s1, s3, s4);
+ }
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_tests.c b/src/dynarec/arm64/dynarec_arm64_emit_tests.c
index bf19058..5c6c602 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_tests.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_tests.c
@@ -111,22 +111,11 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
} else {
SET_DFNONE(s3);
}
- IFX(X_ZF) {
- SUBSw_REG(s5, s1, s2); // res = s1 - s2
- } else {
- SUBw_REG(s5, s1, s2); // res = s1 - s2
- }
+ SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX_PENDOR0 {
STRH_U12(s5, xEmu, offsetof(x64emu_t, res));
}
- IFX(X_ZF) {
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s4, s5, 15);
- BFIw(xFlags, s4, F_SF, 1);
- }
+ COMP_ZFSF(s5, 16)
// bc = (res & (~d | s)) | (~d & s)
IFX(X_CF|X_AF|X_OF) {
MVNw_REG(s4, s1); // s4 = ~d
@@ -170,15 +159,7 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 15); //mask=0xffff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s4, s1, 15);
- BFIw(xFlags, s4, F_SF, 1);
- }
+ COMP_ZFSF(s1, 16)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
@@ -194,22 +175,11 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, in
} else {
SET_DFNONE(s4);
}
- IFX(X_ZF) {
- SUBSw_REG(s5, s1, s2); // res = s1 - s2
- } else {
- SUBw_REG(s5, s1, s2); // res = s1 - s2
- }
+ SUBw_REG(s5, s1, s2); // res = s1 - s2
IFX_PENDOR0 {
STRB_U12(s5, xEmu, offsetof(x64emu_t, res));
}
- IFX(X_ZF) {
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s5, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s5, 8)
// bc = (res & (~d | s)) | (~d & s)
IFX(X_CF|X_AF|X_OF) {
ORNw_REG(s4, s2, s1); // s4 = ~d | s
@@ -251,15 +221,7 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF));
BICw(xFlags, xFlags, s3);
}
- IFX(X_ZF) {
- ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff
- CSETw(s3, cEQ);
- BFIw(xFlags, s3, F_ZF, 1);
- }
- IFX(X_SF) {
- LSRw(s3, s1, 7);
- BFIw(xFlags, s3, F_SF, 1);
- }
+ COMP_ZFSF(s1, 8)
IFX(X_PF) {
emit_pf(dyn, ninst, s1, s3, s4);
}
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 07e4b76..09d053c 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -54,7 +54,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("LOCK ADD Eb, Gb");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
- SMDMB();
GETGB(x2);
if((nextop&0xC0)==0xC0) {
if(rex.rex) {
@@ -70,39 +69,55 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIx(wback, x1, wb2*8, 8);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_add8(dyn, ninst, x1, x2, x4, x5);
- STLXRB(x4, x1, wback);
- CBNZx_MARKLOCK(x4);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDADDALB(x2, x1, wback);
+ emit_add8(dyn, ninst, x1, x2, x4, x5);
+ } else {
+ STADDLB(x2, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_add8(dyn, ninst, x1, x2, x4, x5);
+ STLXRB(x4, x1, wback);
+ CBNZx_MARKLOCK(x4);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 0x01:
INST_NAME("LOCK ADD Ed, Gd");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if((nextop&0xC0)==0xC0) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_add32(dyn, ninst, rex, x1, gd, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDADDALxw(gd, x1, wback);
+ emit_add32(dyn, ninst, rex, x1, gd, x3, x4);
+ } else {
+ STADDLxw(gd, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_add32(dyn, ninst, rex, x1, gd, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 0x08:
INST_NAME("LOCK OR Eb, Gb");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
- SMDMB();
GETGB(x2);
if((nextop&0xC0)==0xC0) {
if(rex.rex) {
@@ -118,32 +133,45 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIx(wback, x1, wb2*8, 8);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_or8(dyn, ninst, x1, x2, x4, x5);
- STLXRB(x4, x1, wback);
- CBNZx_MARKLOCK(x4);
+ if(arm64_atomics) {
+ LDSETALB(x2, x1, wback);
+ UFLAG_IF {
+ emit_or8(dyn, ninst, x1, x2, x4, x5);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_or8(dyn, ninst, x1, x2, x4, x5);
+ STLXRB(x4, x1, wback);
+ CBNZx_MARKLOCK(x4);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 0x09:
INST_NAME("LOCK OR Ed, Gd");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_or32(dyn, ninst, rex, x1, gd, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ LDSETALxw(gd, x1, wback);
+ UFLAG_IF {
+ emit_or32(dyn, ninst, rex, x1, gd, x3, x4);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_or32(dyn, ninst, rex, x1, gd, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
- SMDMB();
break;
case 0x0F:
@@ -176,24 +204,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ORRxw_REG(ed, ed, x4);
} else {
// Will fetch only 1 byte, to avoid alignment issue
- if(rex.w) {
- ANDx_mask(x2, gd, 1, 0, 0b00010); //mask=0x0000000000000007
- } else {
- ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007
- }
- SMDMB();
+ ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
ASRxw(x1, gd, 3); // r1 = (gd>>3)
ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
- MARKLOCK;
- LDAXRB(x1, wback);
ed = x1;
wback = x3;
+ MOV32w(x5, 1);
+ MARKLOCK;
+ LDAXRB(ed, wback);
LSRw_REG(x4, ed, x2);
- ANDw_mask(x4, x4, 0, 0); //mask=1
- BFIw(xFlags, x4, F_CF, 1);
- MOV32w(x4, 1);
- LSLw_REG(x4, x4, x2);
+ BFIw(xFlags, x5, F_CF, 1);
+ LSLw_REG(x4, x5, x2);
ORRw_REG(ed, ed, x4);
STLXRB(x4, ed, wback);
CBNZw_MARKLOCK(x4);
@@ -208,7 +230,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
nextop = F8;
GETGB(x1);
UBFXx(x6, xRAX, 0, 8);
- SMDMB();
if(MODREG) {
if(rex.rex) {
wback = xRAX+(nextop&7)+(rex.b<<3);
@@ -231,19 +252,30 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
B_NEXT_nocond;
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRB(x2, wback);
- CMPSxw_REG(x6, x2);
- B_MARK(cNE);
- // EAX == Ed
- STLXRB(x4, gd, wback);
- CBNZx_MARKLOCK(x4);
- // done
- MARK;
- UFLAG_IF {emit_cmp8(dyn, ninst, x6, x2, x3, x4, x5);}
- BFIx(xRAX, x2, 0, 8);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ MOVw_REG(x2, x6);
+ CASALB(x6, gd, wback);
+ emit_cmp8(dyn, ninst, x2, x6, x3, x4, x5);
+ } else {
+ CASALB(x6, gd, wback);
+ }
+ BFIx(xRAX, x6, 0, 8);
+ } else {
+ MARKLOCK;
+ LDAXRB(x2, wback);
+ CMPSxw_REG(x6, x2);
+ B_MARK(cNE);
+ // EAX == Ed
+ STLXRB(x4, gd, wback);
+ CBNZx_MARKLOCK(x4);
+ // done
+ MARK;
+ UFLAG_IF {emit_cmp8(dyn, ninst, x6, x2, x3, x4, x5);}
+ BFIx(xRAX, x2, 0, 8);
+ }
+ SMDMB();
}
- SMDMB();
break;
default:
DEFAULT;
@@ -256,7 +288,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
wback = 0;
@@ -270,34 +301,58 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
B_NEXT_nocond;
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK3(cNE);
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK3(cNE);
+ }
// Aligned version
- MARKLOCK;
- LDAXRxw(x1, wback);
- CMPSxw_REG(xRAX, x1);
- B_MARK(cNE);
- // EAX == Ed
- STLXRxw(x4, gd, wback);
- CBNZx_MARKLOCK(x4);
- // done
- B_MARK_nocond;
- // Unaligned version
- MARK3;
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x3, wback); // dummy read, to arm the write...
- CMPSxw_REG(xRAX, x1);
- B_MARK(cNE);
- // EAX == Ed
- STLXRB(x4, gd, wback);
- CBNZx_MARK3(x4);
- STRxw_U12(gd, wback, 0);
- MARK;
- // Common part (and fallback for EAX != Ed)
- UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5);}
- MOVxw_REG(xRAX, x1); // upper par of RAX will be erase on 32bits, no mater what
+ if(arm64_atomics) {
+ UFLAG_IF {
+ MOVxw_REG(x1, xRAX);
+ CASALxw(xRAX, gd, wback);
+ SMDMB();
+ emit_cmp32(dyn, ninst, rex, x1, xRAX, x3, x4, x5);
+ } else {
+ CASALxw(xRAX, gd, wback);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ CMPSxw_REG(xRAX, x1);
+ B_MARK(cNE);
+ // EAX == Ed
+ STLXRxw(x4, gd, wback);
+ CBNZx_MARKLOCK(x4);
+ SMDMB();
+ // done
+ if(!ALIGNED_ATOMICxw) {
+ B_MARK_nocond;
+ }
+ }
+ if(!ALIGNED_ATOMICxw) {
+ // Unaligned version
+ MARK3;
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x3, wback); // dummy read, to arm the write...
+ CMPSxw_REG(xRAX, x1);
+ B_MARK(cNE);
+ // EAX == Ed
+ STLXRB(x4, gd, wback);
+ CBNZx_MARK3(x4);
+ STRxw_U12(gd, wback, 0);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw || !arm64_atomics) {
+ MARK;
+ // Common part (and fallback for EAX != Ed)
+ UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5);}
+ MOVxw_REG(xRAX, x1); // upper par of RAX will be erase on 32bits, no mater what
+ }
}
- SMDMB();
break;
default:
DEFAULT;
@@ -330,39 +385,156 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BICxw_REG(ed, ed, x4);
} else {
// Will fetch only 1 byte, to avoid alignment issue
- if(rex.w) {
- ANDx_mask(x2, gd, 1, 0, 0b00010); //mask=0x0000000000000007
- } else {
- ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007
- }
- SMDMB();
+ ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- ASRx(x1, gd, 3); // r1 = (gd>>3)
+ ASRx(x1, gd, 3); // r1 = (gd>>3), there might be an issue for negative 32bits values here
ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
- MARKLOCK;
- LDAXRB(x1, wback);
ed = x1;
wback = x3;
+ MOV32w(x5, 1);
+ MARKLOCK;
+ LDAXRB(ed, wback);
LSRw_REG(x4, ed, x2);
- ANDw_mask(x4, x4, 0, 0); //mask=1
BFIw(xFlags, x4, F_CF, 1);
- MOV32w(x4, 1);
- LSLw_REG(x4, x4, x2);
- ORRw_REG(ed, ed, x4);
+ LSLw_REG(x4, x5, x2);
+ BICw_REG(ed, ed, x4);
STLXRB(x4, ed, wback);
CBNZw_MARKLOCK(x4);
SMDMB();
}
break;
+ case 0xBA:
+ nextop = F8;
+ switch((nextop>>3)&7) {
+ case 4:
+ INST_NAME("LOCK BT Ed, Ib");
+ SETFLAGS(X_CF, SF_SUBSET);
+ SET_DFNONE(x1);
+ gd = x2;
+ if(MODREG) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ u8 = F8;
+ u8&=rex.w?0x3f:0x1f;
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ } else {
+ // Will fetch only 1 byte, to avoid alignment issue
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+ u8 = F8;
+ if(u8>>3) {
+ ADDx_U12(x3, wback, u8>>3);
+ wback = x3;
+ }
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ ed = x1;
+ wback = x3;
+ BFXILxw(xFlags, x1, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ }
+ break;
+ case 5:
+ INST_NAME("LOCK BTS Ed, Ib");
+ SETFLAGS(X_CF, SF_SUBSET);
+ SET_DFNONE(x1);
+ if(MODREG) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ wback = 0;
+ u8 = F8;
+ u8&=(rex.w?0x3f:0x1f);
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ TBNZ_NEXT(xFlags, 0); // bit already set, jump to next instruction
+ MOV32w(x4, 1);
+ ORRxw_REG_LSL(ed, ed, x4, u8);
+ } else {
+ // Will fetch only 1 byte, to avoid alignment issue
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+ u8 = F8;
+ if(u8>>3) {
+ ADDx_U12(x3, wback, u8>>3);
+ wback = x3;
+ }
+ ed = x1;
+ MOV32w(x5, 1);
+ MARKLOCK;
+ LDAXRB(ed, wback);
+ BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ BFIw(ed, x5, u8&7, 1);
+ STLXRB(x4, ed, wback);
+ CBNZw_MARKLOCK(x4);
+ SMDMB();
+ }
+ break;
+ case 6:
+ INST_NAME("LOCK BTR Ed, Ib");
+ SETFLAGS(X_CF, SF_SUBSET);
+ SET_DFNONE(x1);
+ if(MODREG) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ wback = 0;
+ u8 = F8;
+ u8&=(rex.w?0x3f:0x1f);
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ TBZ_NEXT(xFlags, 0); // bit already clear, jump to next instruction
+ BFCxw(ed, u8, 1);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+ u8 = F8;
+ if(u8>>3) {
+ ADDx_U12(x3, wback, u8>>3);
+ wback = x3;
+ }
+ ed = x1;
+ MARKLOCK;
+ LDAXRB(ed, wback);
+ BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ BFCw(ed, u8&7, 1);
+ STLXRB(x4, ed, wback);
+ CBNZw_MARKLOCK(x4);
+ SMDMB();
+ }
+ break;
+ case 7:
+ INST_NAME("LOCK BTC Ed, Ib");
+ SETFLAGS(X_CF, SF_SUBSET);
+ SET_DFNONE(x1);
+ if(MODREG) {
+ ed = xRAX+(nextop&7)+(rex.b<<3);
+ wback = 0;
+ u8 = F8;
+ u8&=(rex.w?0x3f:0x1f);
+ BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ MOV32w(x4, 1);
+ EORxw_REG_LSL(ed, ed, x4, u8);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
+ u8 = F8;
+ if(u8>>3) {
+ ADDx_U12(x3, wback, u8>>3);
+ wback = x3;
+ }
+ ed = x1;
+ MOV32w(x5, 1);
+ MARKLOCK;
+ LDAXRB(ed, wback);
+ BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+ EORw_REG_LSL(ed, ed, x5, u8&7);
+ STLXRB(x4, ed, wback);
+ CBNZw_MARKLOCK(x4);
+ SMDMB();
+ }
+ break;
+ default:
+ DEFAULT;
+ }
+ break;
+
case 0xC1:
switch(rep) {
case 0:
- INST_NAME("LOCK XADD Gd, Ed");
+ INST_NAME("LOCK XADD Ed, Gd");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
MOVxw_REG(x1, ed);
@@ -371,30 +543,54 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE); // unaligned
- MARKLOCK;
- LDAXRxw(x1, wback);
- ADDxw_REG(x4, x1, gd);
- STLXRxw(x3, x4, wback);
- CBNZx_MARKLOCK(x3);
- B_MARK2_nocond;
- MARK;
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIxw(x1, x4, 0, 8);
- ADDxw_REG(x4, x1, gd);
- STLXRB(x3, x4, wback);
- CBNZx_MARK(x3);
- STRxw_U12(x4, wback, 0);
- MARK2;
- IFX(X_ALL|X_PEND) {
- MOVxw_REG(x2, x1);
- emit_add32(dyn, ninst, rex, x2, gd, x3, x4);
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE); // unaligned
+ }
+ if(arm64_atomics) {
+ UFLAG_IF {
+ MOVxw_REG(x3, gd);
+ LDADDALxw(x3, gd, wback);
+ SMDMB();
+ emit_add32(dyn, ninst, rex, x3, gd, x4, x5);
+ } else {
+ LDADDALxw(gd, gd, wback);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ ADDxw_REG(x4, x1, gd);
+ STLXRxw(x3, x4, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ if(!ALIGNED_ATOMICxw) {
+ B_MARK2_nocond;
+ }
+ }
+ if(!ALIGNED_ATOMICxw) {
+ MARK;
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIxw(x1, x4, 0, 8);
+ ADDxw_REG(x4, x1, gd);
+ STLXRB(x3, x4, wback);
+ CBNZx_MARK(x3);
+ STRxw_U12(x4, wback, 0);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw || !arm64_atomics) {
+ MARK2;
+ IFX(X_ALL|X_PEND) {
+ MOVxw_REG(x2, x1);
+ emit_add32(dyn, ninst, rex, x2, gd, x3, x4);
+ }
+ MOVxw_REG(gd, x1);
}
- MOVxw_REG(gd, x1);
}
- SMDMB();
break;
default:
DEFAULT;
@@ -408,24 +604,43 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ZF, SF_SUBSET);
nextop = F8;
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- SMDMB();
- MARKLOCK;
- LDAXPxw(x2, x3, wback);
- CMPSxw_REG(xRAX, x2);
- B_MARK(cNE); // EAX != Ed[0]
- CMPSxw_REG(xRDX, x3);
- B_MARK(cNE); // EDX != Ed[1]
- STLXPxw(x4, xRBX, xRCX, wback);
- CBNZx_MARKLOCK(x4);
- MOV32w(x1, 1);
- B_MARK3_nocond;
- MARK;
- MOVxw_REG(xRAX, x2);
- MOVxw_REG(xRDX, x3);
- MOV32w(x1, 0);
+ if(arm64_atomics) {
+ MOVx_REG(x2, xRAX);
+ MOVx_REG(x3, xRDX);
+ MOVx_REG(x4, xRBX);
+ MOVx_REG(x5, xRCX);
+ CASPALxw(x2, x4, wback);
+ UFLAG_IF {
+ CMPSxw_REG(x2, xRAX);
+ CCMPxw(x3, xRDX, 0, cEQ);
+ CSETw(x1, cEQ);
+ }
+ MOVx_REG(xRAX, x2);
+ MOVx_REG(xRDX, x3);
+ } else {
+ MARKLOCK;
+ LDAXPxw(x2, x3, wback);
+ CMPSxw_REG(xRAX, x2);
+ CCMPxw(xRDX, x3, 0, cEQ);
+ B_MARK(cNE); // EAX!=ED[0] || EDX!=Ed[1]
+ STLXPxw(x4, xRBX, xRCX, wback);
+ CBNZx_MARKLOCK(x4);
+ UFLAG_IF {
+ MOV32w(x1, 1);
+ }
+ B_MARK3_nocond;
+ MARK;
+ MOVxw_REG(xRAX, x2);
+ MOVxw_REG(xRDX, x3);
+ UFLAG_IF {
+ MOV32w(x1, 0);
+ }
+ }
MARK3;
SMDMB();
- BFIw(xFlags, x1, F_ZF, 1);
+ UFLAG_IF {
+ BFIw(xFlags, x1, F_ZF, 1);
+ }
break;
default:
DEFAULT;
@@ -441,7 +656,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
- SMDMB();
GETGB(x2);
if((nextop&0xC0)==0xC0) {
if(rex.rex) {
@@ -462,8 +676,8 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_adc8(dyn, ninst, x1, x2, x4, x5);
STLXRB(x4, x1, wback);
CBNZx_MARKLOCK(x4);
+ SMDMB();
}
- SMDMB();
break;
case 0x11:
INST_NAME("LOCK ADC Ed, Gd");
@@ -471,8 +685,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
- if(MODREG) {
+ if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_adc32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
@@ -482,27 +695,36 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_adc32(dyn, ninst, rex, x1, gd, x4, x5);
STLXRxw(x4, x1, wback);
CBNZx_MARKLOCK(x4);
+ SMDMB();
}
- SMDMB();
break;
case 0x21:
INST_NAME("LOCK AND Ed, Gd");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_and32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_and32(dyn, ninst, rex, x1, gd, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MVNxw_REG(x1, gd);
+ UFLAG_IF {
+ LDCLRALxw(x1, x1, wback);
+ emit_and32(dyn, ninst, rex, x1, gd, x3, x4);
+ } else {
+ STCLRLxw(x1, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_and32(dyn, ninst, rex, x1, gd, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
}
- SMDMB();
break;
case 0x29:
@@ -510,19 +732,28 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_sub32(dyn, ninst, rex, ed, gd, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_sub32(dyn, ninst, rex, x1, gd, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ NEGxw_REG(x1, gd);
+ UFLAG_IF {
+ LDADDALxw(x1, x1, wback);
+ emit_sub32(dyn, ninst, rex, x1, gd, x3, x4);
+ } else {
+ STADDLxw(x1, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_sub32(dyn, ninst, rex, x1, gd, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
}
- SMDMB();
break;
case 0x66:
@@ -530,7 +761,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x80:
nextop = F8;
- SMDMB();
switch((nextop>>3)&7) {
case 0: //ADD
INST_NAME("ADD Eb, Ib");
@@ -545,11 +775,23 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
u8 = F8;
wb1 = 1;
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_add8c(dyn, ninst, x1, u8, x2, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x2, u8);
+ UFLAG_IF {
+ LDADDALB(x2, x1, wback);
+ emit_add8(dyn, ninst, x1, x2, x3, x4);
+ } else {
+ STADDB(x2, wback);
+ }
+
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_add8c(dyn, ninst, x1, u8, x2, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 1: //OR
@@ -565,11 +807,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
u8 = F8;
wb1 = 1;
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_or8c(dyn, ninst, x1, u8, x2, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x2, u8);
+ UFLAG_IF {
+ LDSETALB(x2, x1, wback);
+ emit_or8(dyn, ninst, x1, x2, x3, x4);
+ } else {
+ STSETLB(x2, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_or8c(dyn, ninst, x1, u8, x2, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 2: //ADC
@@ -592,6 +845,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRB(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
+ SMDMB();
break;
case 3: //SBB
INST_NAME("SBB Eb, Ib");
@@ -613,6 +867,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRB(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
+ SMDMB();
break;
case 4: //AND
INST_NAME("AND Eb, Ib");
@@ -627,11 +882,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
u8 = F8;
wb1 = 1;
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_and8c(dyn, ninst, x1, u8, x2, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x2, ~u8);
+ UFLAG_IF {
+ LDCLRALB(x2, x1, wback);
+ emit_and8c(dyn, ninst, x1, u8, x2, x4);
+ } else {
+ STCLRLB(x2, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_and8c(dyn, ninst, x1, u8, x2, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 5: //SUB
@@ -647,11 +913,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
u8 = F8;
wb1 = 1;
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_sub8c(dyn, ninst, x1, u8, x2, x4, x3);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x2, -u8);
+ UFLAG_IF {
+ LDADDALB(x2, x1, wback);
+ emit_sub8c(dyn, ninst, x1, u8, x2, x4, x3);
+ } else {
+ STADDLB(x2, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_sub8c(dyn, ninst, x1, u8, x2, x4, x3);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 6: //XOR
@@ -667,11 +944,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
u8 = F8;
wb1 = 1;
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_xor8c(dyn, ninst, x1, u8, x2, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x2, u8);
+ UFLAG_IF {
+ LDEORALB(x2, x1, wback);
+ emit_xor8(dyn, ninst, x1, x2, x3, x4);
+ } else {
+ STEORLB(x2, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_xor8c(dyn, ninst, x1, u8, x2, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 7: //CMP
@@ -689,12 +977,10 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
default:
DEFAULT;
}
- SMDMB();
break;
case 0x81:
case 0x83:
nextop = F8;
- SMDMB();
switch((nextop>>3)&7) {
case 0: //ADD
if(opcode==0x81) {
@@ -711,23 +997,40 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- SMDMB();
- B_NEXT_nocond;
- MARK; // unaligned! also, not enough
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIxw(x1, x4, 0, 8); // re-inject
- emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
- STLXRB(x3, x1, wback);
- CBNZx_MARK(x3);
- STRxw_U12(x1, wback, 0); // put the whole value
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ MOV64xw(x3, i64);
+ UFLAG_IF {
+ LDADDALxw(x3, x1, wback);
+ SMDMB();
+ emit_add32(dyn, ninst, rex, x1, x3, x4, x5);
+ } else {
+ STADDLxw(x3, wback);
+ SMDMB();
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ MARK; // unaligned! also, not enough
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIxw(x1, x4, 0, 8); // re-inject
+ emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARK(x3);
+ STRxw_U12(x1, wback, 0); // put the whole value
+ SMDMB();
+ }
}
break;
case 1: //OR
@@ -742,11 +1045,21 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
MOV64xw(x5, i64);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_or32(dyn, ninst, rex, x1, x5, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDSETALxw(x5, x1, wback);
+ emit_or32(dyn, ninst, rex, x1, x5, x3, x4);
+ } else {
+ STSETLxw(x5, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_or32(dyn, ninst, rex, x1, x5, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 2: //ADC
@@ -767,6 +1080,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_adc32(dyn, ninst, rex, x1, x5, x3, x4);
STLXRxw(x3, x1, wback);
CBNZx_MARKLOCK(x3);
+ SMDMB();
}
break;
case 3: //SBB
@@ -787,6 +1101,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
emit_sbb32(dyn, ninst, rex, x1, x5, x3, x4);
STLXRxw(x3, x1, wback);
CBNZx_MARKLOCK(x3);
+ SMDMB();
}
break;
case 4: //AND
@@ -800,12 +1115,24 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
- MOV64xw(x5, i64);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_and32(dyn, ninst, rex, x1, x5, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV64xw(x5, ~i64);
+ UFLAG_IF {
+ LDCLRALxw(x5, x1, wback);
+ MVNxw_REG(x5, x5);
+ emit_and32(dyn, ninst, rex, x1, x5, x3, x4);
+ } else {
+ STCLRLxw(x5, wback);
+ }
+ } else {
+ MOV64xw(x5, i64);
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_and32(dyn, ninst, rex, x1, x5, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 5: //SUB
@@ -819,23 +1146,41 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- SMDMB();
- B_NEXT_nocond;
- MARK; // unaligned! also, not enough
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIxw(x1, x4, 0, 8); // re-inject
- emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
- STLXRB(x3, x1, wback);
- CBNZx_MARK(x3);
- STRxw_U12(x1, wback, 0); // put the whole value
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ MOV64xw(x5, -i64);
+ UFLAG_IF {
+ LDADDALxw(x5, x1, wback);
+ SMDMB();
+ NEGxw_REG(x5, x5);
+ emit_sub32(dyn, ninst, rex, x1, x5, x3, x4);
+ } else {
+ STADDLxw(x5, wback);
+ SMDMB();
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ SMDMB();
+ }
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ MARK; // unaligned! also, not enough
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIxw(x1, x4, 0, 8); // re-inject
+ emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARK(x3);
+ STRxw_U12(x1, wback, 0); // put the whole value
+ SMDMB();
+ }
}
break;
case 6: //XOR
@@ -850,11 +1195,21 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
MOV64xw(x5, i64);
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_xor32(dyn, ninst, rex, x1, x5, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ UFLAG_IF {
+ LDEORALxw(x5, x1, wback);
+ emit_xor32(dyn, ninst, rex, x1, x5, x3, x4);
+ } else {
+ STEORLxw(x5, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_xor32(dyn, ninst, rex, x1, x5, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
+ SMDMB();
}
break;
case 7: //CMP
@@ -871,7 +1226,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
}
- SMDMB();
break;
case 0x86:
@@ -887,24 +1241,27 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
ed = (nextop&7);
eb1 = xRAX+(ed&3);
- eb2 = ((ed&4)>>2);
+ eb2 = ((ed&4)<<1);
}
- UBFXw(x1, eb1, eb2*8, 8);
+ UBFXw(x1, eb1, eb2, 8);
// do the swap 14 -> ed, 1 -> gd
- BFIx(gb1, x1, gb2*8, 8);
- BFIx(eb1, x4, eb2*8, 8);
+ BFIx(gb1, x1, gb2, 8);
+ BFIx(eb1, x4, eb2, 8);
} else {
- SMDMB();
GETGB(x4);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- // do the swap with exclusive locking
- LDAXRB(x1, ed);
- // do the swap 14 -> strb(ed), 1 -> gd
- STLXRB(x3, x4, ed);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ SWPALB(x4, x1, ed);
+ } else {
+ MARKLOCK;
+ // do the swap with exclusive locking
+ LDAXRB(x1, ed);
+ // do the swap 14 -> strb(ed), 1 -> gd
+ STLXRB(x3, x4, ed);
+ CBNZx_MARKLOCK(x3);
+ }
+ BFIx(gb1, x1, gb2, 8);
SMDMB();
- BFIx(gb1, x1, gb2*8, 8);
}
break;
case 0x87:
@@ -918,21 +1275,38 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVxw_REG(ed, x1);
} else {
GETGD;
- SMDMB();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE);
- MARKLOCK;
- LDAXRxw(x1, ed);
- STLXRxw(x3, gd, ed);
- CBNZx_MARKLOCK(x3);
- B_MARK2_nocond;
- MARK;
- LDRxw_U12(x1, ed, 0);
- STRxw_U12(gd, ed, 0);
- MARK2;
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE);
+ }
+ if(arm64_atomics) {
+ SWPALxw(gd, gd, ed);
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, ed);
+ STLXRxw(x3, gd, ed);
+ CBNZx_MARKLOCK(x3);
+ if(!ALIGNED_ATOMICxw) {
+ B_MARK2_nocond;
+ }
+ }
+ if(!ALIGNED_ATOMICxw) {
+ MARK;
+ LDRxw_U12(x1, ed, 0);
+ LDAXRB(x3, ed);
+ STLXRB(x3, gd, ed);
+ CBNZx_MARK(x3);
+ STRxw_U12(gd, ed, 0);
+ MARK2;
+ }
SMDMB();
- MOVxw_REG(gd, x1);
+ if(!ALIGNED_ATOMICxw || !arm64_atomics) {
+ MOVxw_REG(gd, x1);
+ }
}
break;
@@ -956,7 +1330,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MVNw_REG(x1, x1);
EBBACK;
} else {
- SMDMB();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
MARKLOCK;
LDAXRB(x1, wback);
@@ -978,7 +1351,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0: // INC Eb
INST_NAME("LOCK INC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
GETEB(x1, 0);
emit_inc8(dyn, ninst, x1, x2, x4);
@@ -986,28 +1358,47 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
MARKLOCK;
- LDAXRB(x1, wback);
- emit_inc8(dyn, ninst, x1, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x3, 1);
+ UFLAG_IF {
+ LDADDALB(x3, x1, wback);
+ emit_inc8(dyn, ninst, x1, x3, x4);
+ } else {
+ STADDLB(x3, wback);
+ }
+ } else {
+ LDAXRB(x1, wback);
+ emit_inc8(dyn, ninst, x1, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
SMDMB();
}
break;
- case 1: //DEC Ed
- INST_NAME("LOCK DEC Ed");
+ case 1: //DEC Eb
+ INST_NAME("LOCK DEC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
GETEB(x1, 0);
emit_dec8(dyn, ninst, x1, x2, x4);
EBBACK;
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- MARKLOCK;
- LDAXRB(x1, wback);
- emit_dec8(dyn, ninst, x1, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
+ if(arm64_atomics) {
+ MOV32w(x3, -1);
+ UFLAG_IF {
+ LDADDALB(x3, x1, wback);
+ emit_dec8(dyn, ninst, x1, x3, x4);
+ } else {
+ STADDLB(x3, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRB(x1, wback);
+ emit_dec8(dyn, ninst, x1, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
SMDMB();
}
break;
@@ -1022,59 +1413,85 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0: // INC Ed
INST_NAME("LOCK INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE); // unaligned
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_inc32(dyn, ninst, rex, x1, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- SMDMB();
- B_NEXT_nocond;
- MARK;
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIxw(x1, x4, 0, 8); // re-inject
- emit_inc32(dyn, ninst, rex, x1, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZw_MARK(x3);
- STRxw_U12(x1, wback, 0);
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE); // unaligned
+ }
+ if(arm64_atomics) {
+ MOV32w(x3, 1);
+ UFLAG_IF {
+ LDADDALxw(x3, x1, wback);
+ emit_inc32(dyn, ninst, rex, x1, x3, x4);
+ } else {
+ STADDLxw(x3, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_inc32(dyn, ninst, rex, x1, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
SMDMB();
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ MARK;
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIxw(x1, x4, 0, 8); // re-inject
+ emit_inc32(dyn, ninst, rex, x1, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZw_MARK(x3);
+ STRxw_U12(x1, wback, 0);
+ SMDMB();
+ }
}
break;
case 1: //DEC Ed
INST_NAME("LOCK DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
- SMDMB();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
- TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
- B_MARK(cNE); // unaligned
- MARKLOCK;
- LDAXRxw(x1, wback);
- emit_dec32(dyn, ninst, rex, x1, x3, x4);
- STLXRxw(x3, x1, wback);
- CBNZx_MARKLOCK(x3);
- SMDMB();
- B_NEXT_nocond;
- MARK;
- LDRxw_U12(x1, wback, 0);
- LDAXRB(x4, wback);
- BFIxw(x1, x4, 0, 8); // re-inject
- emit_dec32(dyn, ninst, rex, x1, x3, x4);
- STLXRB(x3, x1, wback);
- CBNZw_MARK(x3);
- STRxw_U12(x1, wback, 0);
+ if(!ALIGNED_ATOMICxw) {
+ TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7
+ B_MARK(cNE); // unaligned
+ }
+ if(arm64_atomics) {
+ MOV64xw(x3, -1);
+ UFLAG_IF {
+ LDADDALxw(x3, x1, wback);
+ emit_dec32(dyn, ninst, rex, x1, x3, x4);
+ } else {
+ STADDLxw(x3, wback);
+ }
+ } else {
+ MARKLOCK;
+ LDAXRxw(x1, wback);
+ emit_dec32(dyn, ninst, rex, x1, x3, x4);
+ STLXRxw(x3, x1, wback);
+ CBNZx_MARKLOCK(x3);
+ }
SMDMB();
+ if(!ALIGNED_ATOMICxw) {
+ B_NEXT_nocond;
+ MARK;
+ LDRxw_U12(x1, wback, 0);
+ LDAXRB(x4, wback);
+ BFIxw(x1, x4, 0, 8); // re-inject
+ emit_dec32(dyn, ninst, rex, x1, x3, x4);
+ STLXRB(x3, x1, wback);
+ CBNZw_MARK(x3);
+ STRxw_U12(x1, wback, 0);
+ SMDMB();
+ }
}
break;
default:
diff --git a/src/dynarec/arm64/dynarec_arm64_f20f.c b/src/dynarec/arm64/dynarec_arm64_f20f.c
index c2d8a46..7e84e97 100644
--- a/src/dynarec/arm64/dynarec_arm64_f20f.c
+++ b/src/dynarec/arm64/dynarec_arm64_f20f.c
@@ -28,7 +28,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
uint8_t opcode = F8;
uint8_t nextop;
uint8_t gd, ed;
- uint8_t wback;
+ uint8_t wback, wb1, wb2;
uint8_t u8;
uint64_t u64, j64;
int v0, v1;
@@ -159,30 +159,41 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
switch(opcode) {
case 0xF0:
- INST_NAME("(unsupported) CRC32 Gd, Eb)");
+ INST_NAME("CRC32 Gd, Eb");
nextop = F8;
- addr = fakeed(dyn, addr, ninst, nextop);
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
- GETIP(ip);
- STORE_XEMU_CALL(xRIP);
- CALL(native_ud, -1);
- LOAD_XEMU_CALL(xRIP);
- jump_to_epilog(dyn, 0, xRIP, ninst);
- *need_epilog = 0;
- *ok = 0;
+ GETEB(x1, 0);
+ GETGD;
+ if(arm64_crc32) {
+ CRC32CB(gd, gd, ed);
+ } else {
+ EORw_REG(gd, gd, ed);
+ MOV32w(x2, 0x82f63b78);
+ for(int i=0; i<8; ++i) {
+ LSRw_IMM((i&1)?gd:x4, (i&1)?x4:gd, 1);
+ TBZ((i&1)?x4:gd, 0, 4+4);
+ EORw_REG((i&1)?gd:x4, (i&1)?gd:x4, x2);
+ }
+ }
break;
case 0xF1:
- INST_NAME("(unsupported) CRC32 Gd, Ed)");
+ INST_NAME("CRC32 Gd, Ed");
nextop = F8;
- addr = fakeed(dyn, addr, ninst, nextop);
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
- GETIP(ip);
- STORE_XEMU_CALL(xRIP);
- CALL(native_ud, -1);
- LOAD_XEMU_CALL(xRIP);
- jump_to_epilog(dyn, 0, xRIP, ninst);
- *need_epilog = 0;
- *ok = 0;
+ GETED(0);
+ GETGD;
+ if(arm64_crc32) {
+ CRC32Cxw(gd, gd, ed);
+ } else {
+ MOV32w(x2, 0x82f63b78);
+ for(int j=0; j<4*(1+rex.w); ++j) {
+ UBFXxw(x3, ed, 8*j, 8);
+ EORw_REG(gd, gd, x3);
+ for(int i=0; i<8; ++i) {
+ LSRw_IMM((i&1)?gd:x4, (i&1)?x4:gd, 1);
+ TBZ((i&1)?x4:gd, 0, 4+4);
+ EORw_REG((i&1)?gd:x4, (i&1)?gd:x4, x2);
+ }
+ }
+ }
break;
default:
@@ -376,7 +387,22 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
}
VFADDPQS(v0, v0, v1);
break;
-
+ case 0x7D:
+ INST_NAME("HSUBPS Gx, Ex");
+ nextop = F8;
+ GETGX(v0, 1);
+ if(MODREG) {
+ v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 0);
+ v1 = fpu_get_scratch(dyn);
+ VLD128(v1, ed, fixedaddress);
+ }
+ d0 = fpu_get_scratch(dyn);
+ VUZP1Q_32(d0, v0, v1);
+ VUZP2Q_32(v0, v0, v1);
+ VFSUBQS(v0, d0, v0);
+ break;
case 0xC2:
INST_NAME("CMPSD Gx, Ex, Ib");
nextop = F8;
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index 6944b78..27280dc 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -30,7 +30,6 @@
#define XMM8 16
#define X870 8
#define EMM0 8
-#define SCRATCH0 24
// Get a FPU scratch reg
int fpu_get_scratch(dynarec_arm_t* dyn)
@@ -96,6 +95,15 @@ void fpu_reset_reg(dynarec_arm_t* dyn)
}
+int neoncache_no_i64(dynarec_arm_t* dyn, int ninst, int st, int a)
+{
+ if(a==NEON_CACHE_ST_I64) {
+ neoncache_promote_double(dyn, ninst, st);
+ return NEON_CACHE_ST_D;
+ }
+ return a;
+}
+
int neoncache_get_st(dynarec_arm_t* dyn, int ninst, int a)
{
if (dyn->insts[ninst].n.swapped) {
@@ -139,7 +147,7 @@ int neoncache_get_st_f(dynarec_arm_t* dyn, int ninst, int a)
&& dyn->insts[ninst].n.neoncache[i].n==a)
return i;
return -1;
-}
+}
int neoncache_get_st_f_i64(dynarec_arm_t* dyn, int ninst, int a)
{
/*if(a+dyn->insts[ninst].n.stack_next-st<0)
@@ -150,7 +158,7 @@ int neoncache_get_st_f_i64(dynarec_arm_t* dyn, int ninst, int a)
&& dyn->insts[ninst].n.neoncache[i].n==a)
return i;
return -1;
-}
+}
int neoncache_get_st_f_noback(dynarec_arm_t* dyn, int ninst, int a)
{
for(int i=0; i<24; ++i)
@@ -158,7 +166,7 @@ int neoncache_get_st_f_noback(dynarec_arm_t* dyn, int ninst, int a)
&& dyn->insts[ninst].n.neoncache[i].n==a)
return i;
return -1;
-}
+}
int neoncache_get_st_f_i64_noback(dynarec_arm_t* dyn, int ninst, int a)
{
for(int i=0; i<24; ++i)
@@ -166,7 +174,7 @@ int neoncache_get_st_f_i64_noback(dynarec_arm_t* dyn, int ninst, int a)
&& dyn->insts[ninst].n.neoncache[i].n==a)
return i;
return -1;
-}
+}
int neoncache_get_current_st_f(dynarec_arm_t* dyn, int a)
{
for(int i=0; i<24; ++i)
@@ -174,7 +182,7 @@ int neoncache_get_current_st_f(dynarec_arm_t* dyn, int a)
&& dyn->n.neoncache[i].n==a)
return i;
return -1;
-}
+}
int neoncache_get_current_st_f_i64(dynarec_arm_t* dyn, int a)
{
for(int i=0; i<24; ++i)
@@ -182,7 +190,7 @@ int neoncache_get_current_st_f_i64(dynarec_arm_t* dyn, int a)
&& dyn->n.neoncache[i].n==a)
return i;
return -1;
-}
+}
static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int maxinst, int a);
static void neoncache_promote_double_internal(dynarec_arm_t* dyn, int ninst, int maxinst, int a);
static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int maxinst, int a)
@@ -190,7 +198,7 @@ static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int
if(a == dyn->insts[ninst].n.combined1 || a == dyn->insts[ninst].n.combined2) {
if(a == dyn->insts[ninst].n.combined1) {
a = dyn->insts[ninst].n.combined2;
- } else
+ } else
a = dyn->insts[ninst].n.combined1;
int i = neoncache_get_st_f_i64_noback(dyn, ninst, a);
//if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_combined, ninst=%d combined%c %d i=%d (stack:%d/%d)\n", ninst, (a == dyn->insts[ninst].n.combined2)?'2':'1', a ,i, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop);
@@ -314,7 +322,7 @@ static int isCacheEmpty(dynarec_native_t* dyn, int ninst) {
for(int i=0; i<24; ++i)
if(dyn->insts[ninst].n.neoncache[i].v) { // there is something at ninst for i
if(!(
- (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
+ (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
|| dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D
|| dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64)
&& dyn->insts[ninst].n.neoncache[i].n<dyn->insts[ninst].n.stack_pop))
@@ -339,7 +347,7 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
for(int i=0; i<24 && !ret; ++i)
if(dyn->insts[ninst].n.neoncache[i].v) { // there is something at ninst for i
if(!(
- (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
+ (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
|| dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D
|| dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64)
&& dyn->insts[ninst].n.neoncache[i].n<dyn->insts[ninst].n.stack_pop))
@@ -377,7 +385,7 @@ void neoncacheUnwind(neoncache_t* cache)
{
if(cache->swapped) {
// unswap
- int a = -1;
+ int a = -1;
int b = -1;
for(int j=0; j<24 && ((a==-1) || (b==-1)); ++j)
if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F || cache->neoncache[j].t == NEON_CACHE_ST_I64)) {
@@ -580,4 +588,4 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
void print_opcode(dynarec_native_t* dyn, int ninst, uint32_t opcode)
{
dynarec_log(LOG_NONE, "\t%08x\t%s\n", opcode, arm64_print(opcode, (uintptr_t)dyn->block));
-} \ No newline at end of file
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.h b/src/dynarec/arm64/dynarec_arm64_functions.h
index db31887..507a191 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.h
+++ b/src/dynarec/arm64/dynarec_arm64_functions.h
@@ -3,6 +3,8 @@
#include "../dynarec_native_functions.h"
+#define SCRATCH0 24
+
// Get an FPU scratch reg
int fpu_get_scratch(dynarec_arm_t* dyn);
// Reset scratch regs counter
@@ -35,6 +37,9 @@ int neoncache_get_current_st_f_i64(dynarec_arm_t* dyn, int a);
void neoncache_promote_double(dynarec_arm_t* dyn, int ninst, int a);
// Combine and propagate if needed (pass 1 only)
int neoncache_combine_st(dynarec_arm_t* dyn, int ninst, int a, int b); // with stack current dyn->n_stack*
+// Do not allow i64 type
+int neoncache_no_i64(dynarec_arm_t* dyn, int ninst, int st, int a);
+
// FPU Cache transformation (for loops) // Specific, need to be written by backend
int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 13b5835..671bdfe 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -32,6 +32,8 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
{
MAYUSE(dyn); MAYUSE(ninst); MAYUSE(delta);
+ if(l==LOCK_LOCK) { /*SMDMB();*/DMB_ISH(); }
+
if(rex.is32bits)
return geted_32(dyn, addr, ninst, nextop, ed, hint, fixaddress, unscaled, absmax, mask, l, s);
@@ -69,7 +71,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
}
} else {
switch(lock) {
- case 1: addLockAddress(tmp); break;
+ case 1: addLockAddress(tmp); if(fixaddress) *fixaddress=tmp; break;
case 2: if(isLockAddress(tmp)) *l=1; break;
}
MOV64x(ret, tmp);
@@ -106,7 +108,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
ADDx_REG(ret, ret, xRIP);
}
switch(lock) {
- case 1: addLockAddress(addr+delta+tmp); break;
+ case 1: addLockAddress(addr+delta+tmp); if(fixaddress) *fixaddress=addr+delta+tmp; break;
case 2: if(isLockAddress(addr+delta+tmp)) *l=1; break;
}
} else {
@@ -126,7 +128,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u
i64 = F8S;
if(i64==0 || ((i64>=absmin) && (i64<=absmax) && !(i64&mask)) || (unscaled && (i64>-256) && (i64<256))) {
*fixaddress = i64;
- if(unscaled && (i64>-256) && (i64<256))
+ if(unscaled && i64 && (i64>-256) && (i64<256))
*unscaled = 1;
if((nextop&7)==4) {
if (sib_reg!=4) {
@@ -221,7 +223,7 @@ static uintptr_t geted_32(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t
}
} else {
switch(lock) {
- case 1: addLockAddress((int32_t)tmp); break;
+ case 1: addLockAddress((int32_t)tmp); if(fixaddress) *fixaddress=(int32_t)tmp; break;
case 2: if(isLockAddress((int32_t)tmp)) *l=1; break;
}
MOV32w(ret, tmp);
@@ -237,7 +239,7 @@ static uintptr_t geted_32(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t
uint64_t tmp = F32;
MOV32w(ret, tmp);
switch(lock) {
- case 1: addLockAddress(tmp); break;
+ case 1: addLockAddress(tmp); if(fixaddress) *fixaddress=tmp; break;
case 2: if(isLockAddress(tmp)) *l=1; break;
}
} else {
@@ -256,11 +258,11 @@ static uintptr_t geted_32(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t
}
if(nextop&0x80)
i32 = F32S;
- else
+ else
i32 = F8S;
if(i32==0 || ((i32>=absmin) && (i32<=absmax) && !(i32&mask)) || (unscaled && (i32>-256) && (i32<256))) {
*fixaddress = i32;
- if(unscaled && (i32>-256) && (i32<256))
+ if(unscaled && i32 && (i32>-256) && (i32<256))
*unscaled = 1;
if((nextop&7)==4) {
if (sib_reg!=4) {
@@ -567,6 +569,7 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
MAYUSE(dyn); MAYUSE(ninst);
MESSAGE(LOG_DUMP, "Jump to next\n");
+ SMEND();
if(reg) {
if(reg!=xRIP) {
MOVx_REG(xRIP, reg);
@@ -575,6 +578,10 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
uintptr_t tbl = getJumpTable64();
MAYUSE(tbl);
TABLE64(x3, tbl);
+ #ifdef JMPTABL_SHIFT4
+ UBFXx(x2, xRIP, JMPTABL_START4, JMPTABL_SHIFT4);
+ LDRx_REG_LSL3(x3, x3, x2);
+ #endif
UBFXx(x2, xRIP, JMPTABL_START3, JMPTABL_SHIFT3);
LDRx_REG_LSL3(x3, x3, x2);
UBFXx(x2, xRIP, JMPTABL_START2, JMPTABL_SHIFT2);
@@ -598,7 +605,6 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
#ifdef HAVE_TRACE
//MOVx(x3, 15); no access to PC reg
#endif
- SMEND();
BLR(x2); // save LR...
}
@@ -612,16 +618,21 @@ void ret_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex)
if(box64_dynarec_callret) {
// pop the actual return address for ARM stack
LDPx_S7_offset(x2, x6, xSP, 0);
- CBZx(x6, 5*4);
+ CBZx(x6, 6*4);
ADDx_U12(xSP, xSP, 16);
SUBx_REG(x6, x6, xRIP); // is it the right address?
CBNZx(x6, 2*4);
BLR(x2);
- // not the correct return address, regular jump
+ // not the correct return address, regular jump, but purge the stack first, it's unsync now...
+ SUBx_U12(xSP, xSavedSP, 0);
}
uintptr_t tbl = getJumpTable64();
NOTEST(x2);
MOV64x(x2, tbl);
+ #ifdef JMPTABL_SHIFT4
+ UBFXx(x3, xRIP, JMPTABL_START4, JMPTABL_SHIFT4);
+ LDRx_REG_LSL3(x2, x2, x3);
+ #endif
UBFXx(x3, xRIP, JMPTABL_START3, JMPTABL_SHIFT3);
LDRx_REG_LSL3(x2, x2, x3);
UBFXx(x3, xRIP, JMPTABL_START2, JMPTABL_SHIFT2);
@@ -650,16 +661,21 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex, int n)
if(box64_dynarec_callret) {
// pop the actual return address for ARM stack
LDPx_S7_offset(x2, x6, xSP, 0);
- CBZx(x6, 5*4);
+ CBZx(x6, 6*4);
ADDx_U12(xSP, xSP, 16);
SUBx_REG(x6, x6, xRIP); // is it the right address?
CBNZx(x6, 2*4);
BLR(x2);
// not the correct return address, regular jump
+ SUBx_U12(xSP, xSavedSP, 0);
}
uintptr_t tbl = getJumpTable64();
NOTEST(x2);
MOV64x(x2, tbl);
+ #ifdef JMPTABL_SHIFT4
+ UBFXx(x3, xRIP, JMPTABL_START4, JMPTABL_SHIFT4);
+ LDRx_REG_LSL3(x2, x2, x3);
+ #endif
UBFXx(x3, xRIP, JMPTABL_START3, JMPTABL_SHIFT3);
LDRx_REG_LSL3(x2, x2, x3);
UBFXx(x3, xRIP, JMPTABL_START2, JMPTABL_SHIFT2);
@@ -677,6 +693,7 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
//#warning TODO: is64bits
MAYUSE(ninst);
MESSAGE(LOG_DUMP, "IRet to epilog\n");
+ SMEND();
// POP IP
NOTEST(x2);
if(is64bits) {
@@ -711,7 +728,6 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
MOVx_REG(xRSP, x3);
// Ret....
MOV64x(x2, (uintptr_t)arm64_epilog); // epilog on purpose, CS might have changed!
- SMEND();
BR(x2);
CLEARIP();
}
@@ -852,11 +868,11 @@ static void x87_reset(dynarec_arm_t* dyn)
dyn->n.neoncache[i].v = 0;
}
-void x87_stackcount(dynarec_arm_t* dyn, int ninst, int scratch)
+int x87_stackcount(dynarec_arm_t* dyn, int ninst, int scratch)
{
MAYUSE(scratch);
if(!dyn->n.x87stack)
- return;
+ return 0;
if(dyn->n.mmxcount)
mmx_purgecache(dyn, ninst, 0, scratch);
MESSAGE(LOG_DUMP, "\tSynch x87 Stackcount (%d)\n", dyn->n.x87stack);
@@ -879,10 +895,45 @@ void x87_stackcount(dynarec_arm_t* dyn, int ninst, int scratch)
ANDw_mask(scratch, scratch, 0, 2); //mask=7
STRw_U12(scratch, xEmu, offsetof(x64emu_t, top));
// reset x87stack, but not the stack count of neoncache
+ int ret = dyn->n.x87stack;
dyn->n.x87stack = 0;
dyn->n.stack_next -= dyn->n.stack;
dyn->n.stack = 0;
MESSAGE(LOG_DUMP, "\t------x87 Stackcount\n");
+ return ret;
+}
+
+void x87_unstackcount(dynarec_arm_t* dyn, int ninst, int scratch, int count)
+{
+ MAYUSE(scratch);
+ if(!count)
+ return;
+ if(dyn->n.mmxcount)
+ mmx_purgecache(dyn, ninst, 0, scratch);
+ MESSAGE(LOG_DUMP, "\tUnsynch x87 Stackcount (%d)\n", count);
+ int a = -count;
+ // Add x87stack to emu fpu_stack
+ LDRw_U12(scratch, xEmu, offsetof(x64emu_t, fpu_stack));
+ if(a>0) {
+ ADDw_U12(scratch, scratch, a);
+ } else {
+ SUBw_U12(scratch, scratch, -a);
+ }
+ STRw_U12(scratch, xEmu, offsetof(x64emu_t, fpu_stack));
+ // Sub x87stack to top, with and 7
+ LDRw_U12(scratch, xEmu, offsetof(x64emu_t, top));
+ if(a>0) {
+ SUBw_U12(scratch, scratch, a);
+ } else {
+ ADDw_U12(scratch, scratch, -a);
+ }
+ ANDw_mask(scratch, scratch, 0, 2); //mask=7
+ STRw_U12(scratch, xEmu, offsetof(x64emu_t, top));
+ // reset x87stack, but not the stack count of neoncache
+ dyn->n.x87stack = count;
+ dyn->n.stack = count;
+ dyn->n.stack_next += dyn->n.stack;
+ MESSAGE(LOG_DUMP, "\t------x87 Unstackcount\n");
}
int neoncache_st_coherency(dynarec_arm_t* dyn, int ninst, int a, int b)
@@ -1098,7 +1149,11 @@ static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int
if(dyn->n.x87cache[i]!=-1) {
ADDw_U12(s3, s2, dyn->n.x87cache[i]);
ANDw_mask(s3, s3, 0, 2); // mask=7 // (emu->top + i)&7
- VSTR64_REG_LSL3(dyn->n.x87reg[i], s1, s3);
+ if(neoncache_get_st_f(dyn, ninst, dyn->n.x87cache[i])>=0) {
+ FCVT_D_S(SCRATCH0, dyn->n.x87reg[i]);
+ VSTR64_REG_LSL3(SCRATCH0, s1, s3);
+ } else
+ VSTR64_REG_LSL3(dyn->n.x87reg[i], s1, s3);
}
}
@@ -1135,6 +1190,8 @@ int x87_get_current_cache(dynarec_arm_t* dyn, int ninst, int st, int t)
#if STEP == 1
if(t==NEON_CACHE_ST_D && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64))
neoncache_promote_double(dyn, ninst, st);
+ else if(t==NEON_CACHE_ST_I64 && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F))
+ neoncache_promote_double(dyn, ninst, st);
else if(t==NEON_CACHE_ST_F && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64))
neoncache_promote_double(dyn, ninst, st);
#endif
@@ -1232,7 +1289,6 @@ void x87_refresh(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
{
- x87_stackcount(dyn, ninst, s1);
int ret = -1;
for (int i=0; (i<8) && (ret==-1); ++i)
if(dyn->n.x87cache[i] == st)
@@ -1240,8 +1296,9 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
if(ret==-1) // nothing to do
return;
MESSAGE(LOG_DUMP, "\tForget x87 Cache for ST%d\n", st);
+ const int reg = dyn->n.x87reg[ret];
#if STEP == 1
- if(dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_I64)
+ if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F || dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64)
neoncache_promote_double(dyn, ninst, st);
#endif
// prepare offset to fpu => s1
@@ -1249,15 +1306,28 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st)
// Get top
LDRw_U12(s2, xEmu, offsetof(x64emu_t, top));
// Update
- if(st) {
- ADDw_U12(s2, s2, st);
+ int ast = st - dyn->n.x87stack;
+ if(ast) {
+ if(ast>0) {
+ ADDw_U12(s2, s2, ast);
+ } else {
+ SUBw_U12(s2, s2, -ast);
+ }
ANDw_mask(s2, s2, 0, 2); //mask=7 // (emu->top + i)&7
}
- VSTR64_REG_LSL3(dyn->n.x87reg[ret], s1, s2);
+ if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F) {
+ FCVT_D_S(31, reg);
+ VSTR64_REG_LSL3(31, s1, s2);
+ } else if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64) {
+ SCVTFDD(31, reg);
+ VSTR64_REG_LSL3(31, s1, s2);
+ } else {
+ VSTR64_REG_LSL3(reg, s1, s2);
+ }
MESSAGE(LOG_DUMP, "\t--------x87 Cache for ST%d\n", st);
// and forget that cache
- fpu_free_reg(dyn, dyn->n.x87reg[ret]);
- dyn->n.neoncache[dyn->n.x87reg[ret]].v = 0;
+ fpu_free_reg(dyn, reg);
+ dyn->n.neoncache[reg].v = 0;
dyn->n.x87cache[ret] = -1;
dyn->n.x87reg[ret] = -1;
}
@@ -1438,7 +1508,7 @@ static void mmx_reflectcache(dynarec_arm_t* dyn, int ninst, int s1)
{
for (int i=0; i<8; ++i)
if(dyn->n.mmxcache[i]!=-1) {
- VLDR64_U12(dyn->n.mmxcache[i], xEmu, offsetof(x64emu_t, mmx[i]));
+ VSTR64_U12(dyn->n.mmxcache[i], xEmu, offsetof(x64emu_t, mmx[i]));
}
}
@@ -1541,6 +1611,17 @@ static void sse_reflectcache(dynarec_arm_t* dyn, int ninst, int s1)
}
}
+void sse_reflect_reg(dynarec_arm_t* dyn, int ninst, int a)
+{
+ if(dyn->n.ssecache[a].v==-1)
+ return;
+ if(dyn->n.neoncache[dyn->n.ssecache[a].reg].t == NEON_CACHE_XMMW) {
+ VSTR128_U12(dyn->n.ssecache[a].reg, xEmu, offsetof(x64emu_t, xmm[a]));
+ /*dyn->n.neoncache[dyn->n.ssecache[a].reg].t = NEON_CACHE_XMMR;
+ dyn->n.ssecache[a].write = 0;*/
+ }
+}
+
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
{
int start = not07?8:0;
@@ -1573,6 +1654,8 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
for (int i=start; i<16; ++i)
if(dyn->n.ssecache[i].v!=-1) {
VLDR128_U12(dyn->n.ssecache[i].reg, xEmu, offsetof(x64emu_t, xmm[i]));
+ /*dyn->n.ssecache[i].write = 0; // OPTIM: it's sync, so not write anymore
+ dyn->n.neoncache[dyn->n.ssecache[i].reg].t = NEON_CACHE_XMMR;*/
}
MESSAGE(LOG_DUMP, "\t------- Pop XMM Cache (%d)\n", n);
}
@@ -1697,7 +1780,7 @@ static void loadCache(dynarec_arm_t* dyn, int ninst, int stack_cnt, int s1, int
break;
case NEON_CACHE_MM:
MESSAGE(LOG_DUMP, "\t - Loading %s\n", getCacheName(t, n));
- VLDR64_U12(i, xEmu, offsetof(x64emu_t, mmx[i]));
+ VLDR64_U12(i, xEmu, offsetof(x64emu_t, mmx[n]));
break;
case NEON_CACHE_ST_D:
case NEON_CACHE_ST_F:
@@ -1717,9 +1800,11 @@ static void loadCache(dynarec_arm_t* dyn, int ninst, int stack_cnt, int s1, int
ANDw_mask(s3, s3, 0, 2); //mask=7 // (emu->top + i)&7
}
*s3_top += a;
- *s2_val = 0;
- ADDx_REG_LSL(s2, xEmu, s3, 3);
- VLDR64_U12(i, s2, offsetof(x64emu_t, x87));
+ if(*s2_val!=1) {
+ *s2_val = 1;
+ ADDx_U12(s2, xEmu, offsetof(x64emu_t, x87));
+ }
+ VLDR64_REG_LSL3(i, s2, s3);
if(t==NEON_CACHE_ST_F) {
FCVT_S_D(i, i);
}
@@ -1769,14 +1854,16 @@ static void unloadCache(dynarec_arm_t* dyn, int ninst, int stack_cnt, int s1, in
ANDw_mask(s3, s3, 0, 2); //mask=7 // (emu->top + i)&7
}
*s3_top += a;
- ADDx_REG_LSL(s2, xEmu, s3, 3);
- *s2_val = 0;
+ if(*s2_val!=1) {
+ *s2_val = 1;
+ ADDx_U12(s2, xEmu, offsetof(x64emu_t, x87));
+ }
if(t==NEON_CACHE_ST_F) {
FCVT_D_S(i, i);
} else if (t==NEON_CACHE_ST_I64) {
SCVTFDD(i, i);
}
- VSTR64_U12(i, s2, offsetof(x64emu_t, x87));
+ VSTR64_REG_LSL3(i, s2, s3);
break;
case NEON_CACHE_NONE:
case NEON_CACHE_SCR:
@@ -1945,7 +2032,7 @@ static void flagsCacheTransform(dynarec_arm_t* dyn, int ninst, int s1)
if(dyn->f.dfnone) // flags are fully known, nothing we can do more
return;
MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp);
- int go = 0;
+ int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone)?1:0;
switch (dyn->insts[jmp].f_entry.pending) {
case SF_UNKNOWN: break;
case SF_SET:
@@ -1963,12 +2050,10 @@ static void flagsCacheTransform(dynarec_arm_t* dyn, int ninst, int s1)
&& dyn->f.pending!=SF_SET_PENDING
&& dyn->f.pending!=SF_PENDING)
go = 1;
- else
- go = (dyn->insts[jmp].f_entry.dfnone == dyn->f.dfnone)?0:1;
+ else if (dyn->insts[jmp].f_entry.dfnone !=dyn->f.dfnone)
+ go = 1;
break;
}
- if(dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone)
- go = 1;
if(go) {
if(dyn->f.pending!=SF_PENDING) {
LDRw_U12(s1, xEmu, offsetof(x64emu_t, df));
@@ -2016,7 +2101,7 @@ void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
ANDw_mask(s3, s1, 0b011011, 0b000010); // mask=0xE0
LSRw(s3, s3, 5);
- MOV64x(s4, (uintptr_t)GetParityTab());
+ TABLE64(s4, (uintptr_t)GetParityTab());
LDRw_REG_LSL2(s4, s4, s3);
ANDw_mask(s3, s1, 0, 0b000100); //0x1f
LSRw_REG(s4, s4, s3);
@@ -2086,4 +2171,4 @@ void fpu_propagate_stack(dynarec_arm_t* dyn, int ninst)
dyn->n.news = 0;
dyn->n.stack_push = 0;
dyn->n.swapped = 0;
-} \ No newline at end of file
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 5c7c21f..310cd57 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -33,28 +33,31 @@
#define PKip(a) *(uint8_t*)(ip+a)
// Strong mem emulation helpers
-// Sequence of Read will trigger a DMB on "first" read if strongmem is 2
-// Sequence of Write will trigger a DMB on "last" write if strongmem is 1
+#define SMREAD_MIN 2
+#define SMWRITE_MIN 1
+// Sequence of Read will trigger a DMB on "first" read if strongmem is >= SMREAD_MIN
+// Sequence of Write will trigger a DMB on "last" write if strongmem is >= 1
+// All Write operation that might use a lock all have a memory barrier if strongmem is >= SMWRITE_MIN
// Opcode will read
-#define SMREAD() if(!dyn->smread && box64_dynarec_strongmem>1) {SMDMB();}
+#define SMREAD() if((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN)) {SMDMB();} else dyn->smread=1
// Opcode will read with option forced lock
-#define SMREADLOCK(lock) if(lock || (!dyn->smread && box64_dynarec_strongmem>1)) {SMDMB();}
+#define SMREADLOCK(lock) if((lock) || ((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN))) {SMDMB();}
// Opcode might read (depend on nextop)
#define SMMIGHTREAD() if(!MODREG) {SMREAD();}
// Opcode has wrote
#define SMWRITE() dyn->smwrite=1
// Opcode has wrote (strongmem>1 only)
-#define SMWRITE2() if(box64_dynarec_strongmem>1) dyn->smwrite=1
+#define SMWRITE2() if(box64_dynarec_strongmem>SMREAD_MIN) dyn->smwrite=1
// Opcode has wrote with option forced lock
-#define SMWRITELOCK(lock) if(lock) {SMDMB();} else dyn->smwrite=1
+#define SMWRITELOCK(lock) if(lock || (box64_dynarec_strongmem>SMWRITE_MIN)) {SMDMB();} else dyn->smwrite=1
// Opcode might have wrote (depend on nextop)
#define SMMIGHTWRITE() if(!MODREG) {SMWRITE();}
// Start of sequence
#define SMSTART() SMEND()
// End of sequence
-#define SMEND() if(dyn->smwrite && box64_dynarec_strongmem) {DMB_ISH();} dyn->smwrite=0; dyn->smread=0;
+#define SMEND() if(dyn->smwrite && box64_dynarec_strongmem) {if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();}} dyn->smwrite=0; dyn->smread=0;
// Force a Data memory barrier (for LOCK: prefix)
-#define SMDMB() DMB_ISH(); dyn->smwrite=0; dyn->smread=1
+#define SMDMB() if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();} dyn->smwrite=0; dyn->smread=1
//LOCK_* define
#define LOCK_LOCK (int*)1
@@ -66,7 +69,7 @@
ed = xRAX+(nextop&7)+(rex.b<<3); \
wback = 0; \
} else { \
- SMREAD() \
+ SMREAD(); \
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, D); \
LDxw(x1, wback, fixedaddress); \
ed = x1; \
@@ -85,7 +88,7 @@
wback = 0; \
} else { \
SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, D); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(3-rex.is32bits), rex.is32bits?3:7, rex, NULL, 0, D); \
LDz(x1, wback, fixedaddress); \
ed = x1; \
}
@@ -422,6 +425,9 @@
VLD64(a, ed, fixedaddress); \
}
+// Get Ex as 64bits, not a quad (warning, x1 get used)
+#define GETEX64(a, w, D) GETEXSD(a, w, D)
+
// Get Ex as a single, not a quad (warning, x1 get used)
#define GETEXSS(a, w, D) \
if(MODREG) { \
@@ -433,6 +439,20 @@
VLD32(a, ed, fixedaddress); \
}
+// Get Ex as 32bits, not a quad (warning, x1 get used)
+#define GETEX32(a, w, D) GETEXSS(a, w, D)
+
+// Get Ex as 16bits, not a quad (warning, x1 get used)
+#define GETEX16(a, w, D) \
+ if(MODREG) { \
+ a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), w); \
+ } else { \
+ SMREAD(); \
+ a = fpu_get_scratch(dyn); \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, D); \
+ VLD16(a, ed, fixedaddress); \
+ }
+
// Get GM, might use x1, x2 and x3
#define GETGM(a) \
gd = ((nextop&0x38)>>3); \
@@ -464,6 +484,9 @@
TSTw_mask(xFlags, 0b010110, 0); \
CNEGx(r, r, cNE)
+#define ALIGNED_ATOMICxw ((fixedaddress && !(fixedaddress&((1<<(2+rex.w)-1)))) || box64_dynarec_aligned_atomics)
+#define ALIGNED_ATOMICH ((fixedaddress && !(fixedaddress&1)) || box64_dynarec_aligned_atomics)
+
// CALL will use x7 for the call address. Return value can be put in ret (unless ret is -1)
// R0 will not be pushed/popd if ret is -2
#define CALL(F, ret) call_c(dyn, ninst, F, x7, ret, 1, 0)
@@ -742,8 +765,39 @@
LDP_REGS(R12, R13); \
LDP_REGS(R14, R15)
+#define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \
+ if (dyn->n.stack == +8) { \
+ *ok = 0; \
+ break; \
+ } \
+ var = x87_do_push(dyn, ninst, scratch, t);
+
+#define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \
+ if (dyn->n.stack == +8) { \
+ *ok = 0; \
+ break; \
+ } \
+ x87_do_push_empty(dyn, ninst, scratch);
+
+#define X87_POP_OR_FAIL(dyn, ninst, scratch) \
+ if (dyn->n.stack == -8) { \
+ *ok = 0; \
+ break; \
+ } \
+ x87_do_pop(dyn, ninst, scratch);
+
#define SET_DFNONE(S) if(!dyn->f.dfnone) {STRw_U12(wZR, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=1;}
-#define SET_DF(S, N) if((N)!=d_none) {MOVZw(S, (N)); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=0;} else SET_DFNONE(S)
+#define SET_DF(S, N) \
+ if((N)!=d_none) { \
+ MOVZw(S, (N)); \
+ STRw_U12(S, xEmu, offsetof(x64emu_t, df)); \
+ if(dyn->f.pending==SF_PENDING && dyn->insts[ninst].x64.need_after && !(dyn->insts[ninst].x64.need_after&X_PEND)) { \
+ CALL_(UpdateFlags, -1, 0); \
+ dyn->f.pending = SF_SET; \
+ SET_NODF(); \
+ } \
+ dyn->f.dfnone=0; \
+ } else SET_DFNONE(S)
#define SET_NODF() dyn->f.dfnone = 0
#define SET_DFOK() dyn->f.dfnone = 1
@@ -784,7 +838,7 @@
} else dyn->f.pending = SF_SET
#endif
#ifndef JUMP
-#define JUMP(A, C)
+#define JUMP(A, C) SMEND()
#endif
#ifndef BARRIER
#define BARRIER(A)
@@ -792,6 +846,9 @@
#ifndef BARRIER_NEXT
#define BARRIER_NEXT(A)
#endif
+#ifndef SET_HASCALLRET
+#define SET_HASCALLRET()
+#endif
#define UFLAG_OP1(A) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op1));}
#define UFLAG_OP2(A) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op2));}
#define UFLAG_OP12(A1, A2) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A1, xEmu, offsetof(x64emu_t, op1));STRxw_U12(A2, xEmu, offsetof(x64emu_t, op2));}
@@ -874,6 +931,8 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define dynarec64_65 STEPNAME(dynarec64_65)
#define dynarec64_66 STEPNAME(dynarec64_66)
#define dynarec64_67 STEPNAME(dynarec64_67)
+#define dynarec64_67_32 STEPNAME(dynarec64_67_32)
+#define dynarec64_6764_32 STEPNAME(dynarec64_6764_32)
#define dynarec64_D8 STEPNAME(dynarec64_D8)
#define dynarec64_D9 STEPNAME(dynarec64_D9)
#define dynarec64_DA STEPNAME(dynarec64_DA)
@@ -884,6 +943,8 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define dynarec64_DF STEPNAME(dynarec64_DF)
#define dynarec64_F0 STEPNAME(dynarec64_F0)
#define dynarec64_660F STEPNAME(dynarec64_660F)
+#define dynarec64_66F20F STEPNAME(dynarec64_66F20F)
+#define dynarec64_66F30F STEPNAME(dynarec64_66F30F)
#define dynarec64_6664 STEPNAME(dynarec64_6664)
#define dynarec64_66F0 STEPNAME(dynarec64_66F0)
#define dynarec64_F20F STEPNAME(dynarec64_F20F)
@@ -965,16 +1026,38 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define emit_shr32 STEPNAME(emit_shr32)
#define emit_shr32c STEPNAME(emit_shr32c)
#define emit_sar32c STEPNAME(emit_sar32c)
+#define emit_shl8 STEPNAME(emit_shl8)
+#define emit_shl8c STEPNAME(emit_shl8c)
+#define emit_shr8 STEPNAME(emit_shr8)
+#define emit_shr8c STEPNAME(emit_shr8c)
+#define emit_sar8 STEPNAME(emit_sar8)
+#define emit_sar8c STEPNAME(emit_sar8c)
+#define emit_shl16 STEPNAME(emit_shl16)
+#define emit_shl16c STEPNAME(emit_shl16c)
+#define emit_shr16 STEPNAME(emit_shr16)
+#define emit_shr16c STEPNAME(emit_shr16c)
+#define emit_sar16 STEPNAME(emit_sar16)
+#define emit_sar16c STEPNAME(emit_sar16c)
#define emit_rol32c STEPNAME(emit_rol32c)
#define emit_ror32c STEPNAME(emit_ror32c)
+#define emit_rol8c STEPNAME(emit_rol8c)
+#define emit_ror8c STEPNAME(emit_ror8c)
+#define emit_rol16c STEPNAME(emit_rol16c)
+#define emit_ror16c STEPNAME(emit_ror16c)
#define emit_shrd32c STEPNAME(emit_shrd32c)
+#define emit_shrd32 STEPNAME(emit_shrd32)
#define emit_shld32c STEPNAME(emit_shld32c)
+#define emit_shld32 STEPNAME(emit_shld32)
+#define emit_shrd16c STEPNAME(emit_shrd16c)
+#define emit_shrd16 STEPNAME(emit_shrd16)
+#define emit_shld16c STEPNAME(emit_shld16c)
+#define emit_shld16 STEPNAME(emit_shld16)
#define emit_pf STEPNAME(emit_pf)
-#define x87_do_push STEPNAME(x87_do_push)
-#define x87_do_push_empty STEPNAME(x87_do_push_empty)
-#define x87_do_pop STEPNAME(x87_do_pop)
+#define x87_do_push STEPNAME(x87_do_push)
+#define x87_do_push_empty STEPNAME(x87_do_push_empty)
+#define x87_do_pop STEPNAME(x87_do_pop)
#define x87_get_current_cache STEPNAME(x87_get_current_cache)
#define x87_get_cache STEPNAME(x87_get_cache)
#define x87_get_neoncache STEPNAME(x87_get_neoncache)
@@ -984,6 +1067,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define x87_forget STEPNAME(x87_forget)
#define x87_reget_st STEPNAME(x87_reget_st)
#define x87_stackcount STEPNAME(x87_stackcount)
+#define x87_unstackcount STEPNAME(x87_unstackcount)
#define x87_swapreg STEPNAME(x87_swapreg)
#define x87_setround STEPNAME(x87_setround)
#define x87_restoreround STEPNAME(x87_restoreround)
@@ -994,6 +1078,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define sse_get_reg_empty STEPNAME(sse_get_reg_empty)
#define sse_forget_reg STEPNAME(sse_forget_reg)
#define sse_purge07cache STEPNAME(sse_purge07cache)
+#define sse_reflect_reg STEPNAME(sse_reflect_reg)
#define fpu_pushcache STEPNAME(fpu_pushcache)
#define fpu_popcache STEPNAME(fpu_popcache)
@@ -1092,16 +1177,40 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4);
void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
+void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
+void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4);
void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4);
+void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4);
+void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s5, int s3, int s4);
+void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int s3, int s4);
+void emit_shrd16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, int s4);
+void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int s3, int s4);
+void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, int s4);
void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4);
// x87 helper
-// cache of the local stack counter, to avoid update at every call
-void x87_stackcount(dynarec_arm_t* dyn, int ninst, int scratch);
+// cache of the local stack counter, to avoid update at every call, return old internal stack counter
+int x87_stackcount(dynarec_arm_t* dyn, int ninst, int scratch);
+// revert local stack counter to previous version (return from x87_stackcount)
+void x87_unstackcount(dynarec_arm_t* dyn, int ninst, int scratch, int count);
// fpu push. Return the Dd value to be used
int x87_do_push(dynarec_arm_t* dyn, int ninst, int s1, int t);
// fpu push. Do not allocate a cache register. Needs a scratch register to do x87stack synch (or 0 to not do it)
@@ -1154,8 +1263,8 @@ int neoncache_st_coherency(dynarec_arm_t* dyn, int ninst, int a, int b);
#define ST_IS_F(A) (neoncache_get_current_st(dyn, ninst, A)==NEON_CACHE_ST_F)
#define ST_IS_I64(A) (neoncache_get_current_st(dyn, ninst, A)==NEON_CACHE_ST_I64)
#define X87_COMBINE(A, B) neoncache_combine_st(dyn, ninst, A, B)
-#define X87_ST0 neoncache_get_current_st(dyn, ninst, 0)
-#define X87_ST(A) neoncache_get_current_st(dyn, ninst, A)
+#define X87_ST0 neoncache_no_i64(dyn, ninst, 0, neoncache_get_current_st(dyn, ninst, 0))
+#define X87_ST(A) neoncache_no_i64(dyn, ninst, A, neoncache_get_current_st(dyn, ninst, A))
#else
#define ST_IS_F(A) (neoncache_get_st(dyn, ninst, A)==NEON_CACHE_ST_F)
#define ST_IS_I64(A) (neoncache_get_st(dyn, ninst, A)==NEON_CACHE_ST_I64)
@@ -1183,7 +1292,8 @@ int sse_get_reg_empty(dynarec_arm_t* dyn, int ninst, int s1, int a);
void sse_forget_reg(dynarec_arm_t* dyn, int ninst, int a);
// purge the XMM0..XMM7 cache (before function call)
void sse_purge07cache(dynarec_arm_t* dyn, int ninst, int s1);
-
+// Push current value to the cache
+void sse_reflect_reg(dynarec_arm_t* dyn, int ninst, int a);
// common coproc helpers
// reset the cache
void fpu_reset(dynarec_arm_t* dyn);
@@ -1208,16 +1318,20 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
//uintptr_t dynarec64_65(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog);
uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-//uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_66F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog);
uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
@@ -1354,4 +1468,30 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
opcode = F8; \
}
+#define COMP_ZFSF(s1, A) \
+ IFX(X_ZF|X_SF) { \
+ if(arm64_flagm) { \
+ SETF##A(s1); \
+ IFX(X_ZF) { \
+ CSETw(s3, cEQ); \
+ BFIw(xFlags, s3, F_ZF, 1); \
+ } \
+ IFX(X_SF) { \
+ CSETw(s3, cMI); \
+ BFIw(xFlags, s3, F_SF, 1); \
+ } \
+ } else { \
+ IFX(X_ZF) { \
+ ANDSw_mask(s1, s1, 0, (A)-1); \
+ CSETw(s3, cEQ); \
+ BFIw(xFlags, s3, F_ZF, 1); \
+ } \
+ IFX(X_SF) { \
+ LSRw(s3, s1, (A)-1); \
+ BFIw(xFlags, s3, F_SF, 1); \
+ } \
+ } \
+ }
+
+
#endif //__DYNAREC_ARM64_HELPER_H__
diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h
index 774d13d..918bb3c 100644
--- a/src/dynarec/arm64/dynarec_arm64_pass0.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass0.h
@@ -16,9 +16,10 @@
dyn->f.pending=(B)&SF_SET_PENDING; \
dyn->f.dfnone=((B)&SF_SET)?1:0;
#define EMIT(A)
-#define JUMP(A, C) add_next(dyn, (uintptr_t)A); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
+#define JUMP(A, C) add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
#define BARRIER(A) if(A!=BARRIER_MAYBE) {fpu_purgecache(dyn, ninst, 0, x1, x2, x3); dyn->insts[ninst].x64.barrier = A;} else dyn->insts[ninst].barrier_maybe = 1
-#define BARRIER_NEXT(A) dyn->insts[ninst+1].x64.barrier = A
+#define BARRIER_NEXT(A) dyn->insts[ninst].x64.barrier_next = A
+#define SET_HASCALLRET() dyn->insts[ninst].x64.has_callret = 1
#define NEW_INST \
++dyn->size; \
if(dyn->size+3>=dyn->cap) { \
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index 6ac79d7..0e5c0e9 100644
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -102,6 +102,9 @@ typedef struct dynarec_arm_s {
uintptr_t* next; // variable array of "next" jump address
int next_sz;
int next_cap;
+ int* jmps; // variable array of jump instructions
+ int jmp_sz;
+ int jmp_cap;
int* predecessor;// single array of all predecessor
dynablock_t* dynablock;
instsize_t* instsize;
@@ -119,6 +122,8 @@ typedef struct dynarec_arm_s {
void add_next(dynarec_arm_t *dyn, uintptr_t addr);
uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr);
+void add_jump(dynarec_arm_t *dyn, int ninst);
+int get_first_jump(dynarec_arm_t *dyn, int next);
int is_nops(dynarec_arm_t *dyn, uintptr_t addr, int n);
int is_instructions(dynarec_arm_t *dyn, uintptr_t addr, int n);
@@ -126,7 +131,7 @@ int Table64(dynarec_arm_t *dyn, uint64_t val, int pass); // add a value to tabl
void CreateJmpNext(void* addr, void* next);
-#define GO_TRACE(A, B) \
+#define GO_TRACE(A, B, s0) \
GETIP(addr); \
MOVx_REG(x1, xRIP); \
STORE_XEMU_CALL(xRIP); \
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 114479b..d624019 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -41,10 +41,10 @@ dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock)
if(db->gone)
return NULL; // already in the process of deletion!
dynarec_log(LOG_DEBUG, "InvalidDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone);
+ // remove jumptable without waiting
+ setJumpTableDefault64(db->x64_addr);
if(need_lock)
mutex_lock(&my_context->mutex_dyndump);
- // remove jumptable
- setJumpTableDefault64(db->x64_addr);
db->done = 0;
db->gone = 1;
if(need_lock)
@@ -74,10 +74,10 @@ void FreeDynablock(dynablock_t* db, int need_lock)
if(db->gone)
return; // already in the process of deletion!
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone);
+ // remove jumptable without waiting
+ setJumpTableDefault64(db->x64_addr);
if(need_lock)
mutex_lock(&my_context->mutex_dyndump);
- // remove jumptable
- setJumpTableDefault64(db->x64_addr);
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size);
db->done = 0;
db->gone = 1;
@@ -171,11 +171,16 @@ dynablock_t *AddNewDynablock(uintptr_t addr)
}
//TODO: move this to dynrec_arm.c and track allocated structure to avoid memory leak
-static __thread struct __jmp_buf_tag dynarec_jmpbuf;
+static __thread JUMPBUFF dynarec_jmpbuf;
+#ifdef ANDROID
+#define DYN_JMPBUF dynarec_jmpbuf
+#else
+#define DYN_JMPBUF &dynarec_jmpbuf
+#endif
void cancelFillBlock()
{
- longjmp(&dynarec_jmpbuf, 1);
+ longjmp(DYN_JMPBUF, 1);
}
/*
@@ -208,7 +213,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
// fill the block
block->x64_addr = (void*)addr;
- if(sigsetjmp(&dynarec_jmpbuf, 1)) {
+ if(sigsetjmp(DYN_JMPBUF, 1)) {
printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, canceling\n", (void*)addr);
FreeDynablock(block, 0);
if(need_lock)
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index bb6b3ba..a46997f 100644
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -81,16 +81,38 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
uint64_t old_rsi = R_RSI;
uint64_t old_rbp = R_RBP;
uint64_t old_rip = R_RIP;
+ // save defered flags
+ deferred_flags_t old_df = emu->df;
+ multiuint_t old_op1 = emu->op1;
+ multiuint_t old_op2 = emu->op2;
+ multiuint_t old_res = emu->res;
+ multiuint_t old_op1_sav= emu->op1_sav;
+ multiuint_t old_res_sav= emu->res_sav;
+ deferred_flags_t old_df_sav= emu->df_sav;
+ // uc_link
+ x64_ucontext_t* old_uc_link = emu->uc_link;
+ emu->uc_link = NULL;
+
PushExit(emu);
R_RIP = addr;
emu->df = d_none;
DynaRun(emu);
emu->quit = 0; // reset Quit flags...
emu->df = d_none;
+ emu->uc_link = old_uc_link;
if(emu->flags.quitonlongjmp && emu->flags.longjmp) {
if(emu->flags.quitonlongjmp==1)
emu->flags.longjmp = 0; // don't change anything because of the longjmp
} else {
+ // restore defered flags
+ emu->df = old_df;
+ emu->op1 = old_op1;
+ emu->op2 = old_op2;
+ emu->res = old_res;
+ emu->op1_sav = old_op1_sav;
+ emu->res_sav = old_res_sav;
+ emu->df_sav = old_df_sav;
+ // and the old registers
R_RBX = old_rbx;
R_RDI = old_rdi;
R_RSI = old_rsi;
@@ -100,19 +122,25 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
}
}
+int my_setcontext(x64emu_t* emu, void* ucp);
void DynaRun(x64emu_t* emu)
{
// prepare setjump for signal handling
- struct __jmp_buf_tag jmpbuf[1] = {0};
+ JUMPBUFF jmpbuf[1] = {0};
int skip = 0;
- struct __jmp_buf_tag *old_jmpbuf = emu->jmpbuf;
+ JUMPBUFF *old_jmpbuf = emu->jmpbuf;
emu->flags.jmpbuf_ready = 0;
while(!(emu->quit)) {
if(!emu->jmpbuf || (emu->flags.need_jmpbuf && emu->jmpbuf!=jmpbuf)) {
emu->jmpbuf = jmpbuf;
emu->flags.jmpbuf_ready = 1;
- if((skip=sigsetjmp(emu->jmpbuf, 1))) {
+ #ifdef ANDROID
+ if((skip=sigsetjmp(*(JUMPBUFF*)emu->jmpbuf, 1)))
+ #else
+ if((skip=sigsetjmp(emu->jmpbuf, 1)))
+ #endif
+ {
printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]);
#ifdef DYNAREC
if(box64_dynarec_test) {
@@ -134,7 +162,7 @@ void DynaRun(x64emu_t* emu)
else {
int is32bits = (emu->segs[_CS]==0x23);
dynablock_t* block = (skip)?NULL:DBGetBlock(emu, R_RIP, 1, is32bits);
- if(!block || !block->block || !block->done) {
+ if(!block || !block->block || !block->done || ACCESS_FLAG(F_TF)) {
skip = 0;
// no block, of block doesn't have DynaRec content (yet, temp is not null)
// Use interpreter (should use single instruction step...)
@@ -153,6 +181,10 @@ void DynaRun(x64emu_t* emu)
emu->fork = 0;
emu = x64emu_fork(emu, forktype);
}
+ if(emu->quit && emu->uc_link) {
+ emu->quit = 0;
+ my_setcontext(emu, emu->uc_link);
+ }
}
#endif
if(emu->flags.need_jmpbuf)
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 2aade27..94898c2 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -94,6 +94,21 @@ uintptr_t get_closest_next(dynarec_native_t *dyn, uintptr_t addr) {
}
return best;
}
+void add_jump(dynarec_native_t *dyn, int ninst) {
+ // add slots
+ if(dyn->jmp_sz == dyn->jmp_cap) {
+ dyn->jmp_cap += 64;
+ dyn->jmps = (int*)dynaRealloc(dyn->jmps, dyn->jmp_cap*sizeof(int));
+ }
+ dyn->jmps[dyn->jmp_sz++] = ninst;
+}
+int get_first_jump(dynarec_native_t *dyn, int next) {
+ for(int i=0; i<dyn->jmp_sz; ++i)
+ if(dyn->insts[dyn->jmps[i]].x64.jmp == next)
+ return i;
+ return -2;
+}
+
#define PK(A) (*((uint8_t*)(addr+(A))))
int is_nops(dynarec_native_t *dyn, uintptr_t addr, int n)
{
@@ -356,11 +371,11 @@ static int updateNeed(dynarec_native_t* dyn, int ninst, uint8_t need) {
dyn->insts[ninst].x64.gen_flags |= X_PEND;
dyn->insts[ninst].x64.need_after = need;
need = dyn->insts[ninst].x64.need_after&~dyn->insts[ninst].x64.gen_flags;
+
if(dyn->insts[ninst].x64.may_set)
need |= dyn->insts[ninst].x64.gen_flags; // forward the flags
- // Consume X_PEND if relevant
- if((need&X_PEND) && (dyn->insts[ninst].x64.set_flags&SF_PENDING))
- need &=~X_PEND;
+ else if((need&X_PEND) && (dyn->insts[ninst].x64.set_flags&SF_PENDING))
+ need &=~X_PEND; // Consume X_PEND if relevant
need |= dyn->insts[ninst].x64.use_flags;
if(dyn->insts[ninst].x64.need_before == need)
return ninst - 1;
@@ -392,6 +407,7 @@ void CancelBlock64(int need_lock)
current_helper = NULL;
if(helper) {
dynaFree(helper->next);
+ dynaFree(helper->jmps);
dynaFree(helper->insts);
dynaFree(helper->predecessor);
if(helper->table64 && (helper->table64!=(uint64_t*)helper->tablestart))
@@ -471,10 +487,6 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
helper.insts = (instruction_native_t*)dynaCalloc(helper.cap, sizeof(instruction_native_t));
// pass 0, addresses, x64 jump addresses, overall size of the block
uintptr_t end = native_pass0(&helper, addr, alternate, is32bits);
- // no need for next anymore
- dynaFree(helper.next);
- helper.next_sz = helper.next_cap = 0;
- helper.next = NULL;
// basic checks
if(!helper.size) {
dynarec_log(LOG_INFO, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
@@ -493,26 +505,57 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
// compute hash signature
uint32_t hash = X31_hash_code((void*)addr, end-addr);
// calculate barriers
- for(int i=0; i<helper.size; ++i)
- if(helper.insts[i].x64.jmp) {
- uintptr_t j = helper.insts[i].x64.jmp;
- if(j<start || j>=end || j==helper.insts[i].x64.addr) {
- if(j==helper.insts[i].x64.addr) // if there is a loop on some opcode, make the block "always to tested"
- helper.always_test = 1;
- helper.insts[i].x64.jmp_insts = -1;
- helper.insts[i].x64.need_after |= X_PEND;
- } else {
- // find jump address instruction
- int k=-1;
- for(int i2=0; i2<helper.size && k==-1; ++i2) {
- if(helper.insts[i2].x64.addr==j)
- k=i2;
+ for(int ii=0; ii<helper.jmp_sz; ++ii) {
+ int i = helper.jmps[ii];
+ uintptr_t j = helper.insts[i].x64.jmp;
+ if(j<start || j>=end || j==helper.insts[i].x64.addr) {
+ if(j==helper.insts[i].x64.addr) // if there is a loop on some opcode, make the block "always to tested"
+ helper.always_test = 1;
+ helper.insts[i].x64.jmp_insts = -1;
+ helper.insts[i].x64.need_after |= X_PEND;
+ } else {
+ // find jump address instruction
+ int k=-1;
+ int search = ((j>=helper.insts[0].x64.addr) && j<helper.insts[0].x64.addr+helper.isize)?1:0;
+ int imin = 0;
+ int imax = helper.size-1;
+ int i2 = helper.size/2;
+ // dichotomy search
+ while(search) {
+ if(helper.insts[i2].x64.addr == j) {
+ k = i2;
+ search = 0;
+ } else if(helper.insts[i2].x64.addr>j) {
+ imax = i2;
+ i2 = (imax+imin)/2;
+ } else {
+ imin = i2;
+ i2 = (imax+imin)/2;
+ }
+ if(search && (imax-imin)<2) {
+ search = 0;
+ if(helper.insts[imin].x64.addr==j)
+ k = imin;
+ else if(helper.insts[imax].x64.addr==j)
+ k = imax;
}
- if(k!=-1 && !helper.insts[i].barrier_maybe)
- helper.insts[k].x64.barrier |= BARRIER_FULL;
- helper.insts[i].x64.jmp_insts = k;
}
+ /*for(int i2=0; i2<helper.size && k==-1; ++i2) {
+ if(helper.insts[i2].x64.addr==j)
+ k=i2;
+ }*/
+ if(k!=-1 && !helper.insts[i].barrier_maybe)
+ helper.insts[k].x64.barrier |= BARRIER_FULL;
+ helper.insts[i].x64.jmp_insts = k;
}
+ }
+ // no need for next and jmps anymore
+ dynaFree(helper.next);
+ helper.next_sz = helper.next_cap = 0;
+ helper.next = NULL;
+ dynaFree(helper.jmps);
+ helper.jmp_sz = helper.jmp_cap = 0;
+ helper.jmps = NULL;
// fill predecessors with the jump address
fillPredecessors(&helper);
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index 7f4ec40..07dad6b 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -66,12 +66,24 @@ void native_fxtract(x64emu_t* emu)
}
void native_fprem(x64emu_t* emu)
{
- int32_t tmp32s = ST0.d / ST1.d;
- ST0.d -= ST1.d * tmp32s;
- emu->sw.f.F87_C2 = 0;
- emu->sw.f.F87_C1 = (tmp32s&1);
- emu->sw.f.F87_C3 = ((tmp32s>>1)&1);
- emu->sw.f.F87_C0 = ((tmp32s>>2)&1);
+ int e0, e1;
+ int64_t ll;
+ frexp(ST0.d, &e0);
+ frexp(ST1.d, &e1);
+ int32_t tmp32s = e0 - e1;
+ if(tmp32s<64)
+ {
+ ll = (int64_t)floor(ST0.d/ST1.d);
+ ST0.d = ST0.d - (ST1.d*ll);
+ emu->sw.f.F87_C2 = 0;
+ emu->sw.f.F87_C1 = (ll&1)?1:0;
+ emu->sw.f.F87_C3 = (ll&2)?1:0;
+ emu->sw.f.F87_C0 = (ll&4)?1:0;
+ } else {
+ ll = (int64_t)(floor((ST0.d/ST1.d))/exp2(tmp32s - 32));
+ ST0.d = ST0.d - ST1.d*ll*exp2(tmp32s - 32);
+ emu->sw.f.F87_C2 = 1;
+ }
}
void native_fyl2xp1(x64emu_t* emu)
{
@@ -174,6 +186,17 @@ void native_singlestep(x64emu_t* emu)
emit_signal(emu, SIGTRAP, (void*)R_RIP, 1);
}
+void native_int3(x64emu_t* emu)
+{
+ emit_signal(emu, SIGTRAP, (void*)R_RIP, 128);
+}
+
+void native_div0(x64emu_t* emu)
+{
+ emu->test.test = 0;
+ emit_div0(emu, (void*)R_RIP, 0);
+}
+
void native_fsave(x64emu_t* emu, uint8_t* ed)
{
fpu_savenv(emu, (char*)ed, 0);
@@ -200,13 +223,24 @@ void native_frstor(x64emu_t* emu, uint8_t* ed)
void native_fprem1(x64emu_t* emu)
{
- // simplified version
- int32_t tmp32s = round(ST0.d / ST1.d);
- ST0.d -= ST1.d*tmp32s;
- emu->sw.f.F87_C2 = 0;
- emu->sw.f.F87_C1 = (tmp32s&1);
- emu->sw.f.F87_C3 = ((tmp32s>>1)&1);
- emu->sw.f.F87_C0 = ((tmp32s>>2)&1);
+ int e0, e1;
+ int64_t ll;
+ frexp(ST0.d, &e0);
+ frexp(ST1.d, &e1);
+ int32_t tmp32s = e0 - e1;
+ if(tmp32s<64)
+ {
+ ll = (int64_t)round(ST0.d/ST1.d);
+ ST0.d = ST0.d - (ST1.d*ll);
+ emu->sw.f.F87_C2 = 0;
+ emu->sw.f.F87_C1 = (ll&1)?1:0;
+ emu->sw.f.F87_C3 = (ll&2)?1:0;
+ emu->sw.f.F87_C0 = (ll&4)?1:0;
+ } else {
+ ll = (int64_t)(trunc((ST0.d/ST1.d))/exp2(tmp32s - 32));
+ ST0.d = ST0.d - ST1.d*ll*exp2(tmp32s - 32);
+ emu->sw.f.F87_C2 = 1;
+ }
}
static uint8_t ff_mult(uint8_t a, uint8_t b)
@@ -371,9 +405,8 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
return 0;
if(dyn->insts[ninst].f_exit.dfnone) // flags are fully known, nothing we can do more
return 0;
-/* if((dyn->f.pending!=SF_SET)
- && (dyn->f.pending!=SF_SET_PENDING)) {
- if(dyn->f.pending!=SF_PENDING) {*/
+ if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone)
+ return 1;
switch (dyn->insts[jmp].f_entry.pending) {
case SF_UNKNOWN: return 0;
case SF_SET:
@@ -382,22 +415,14 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) {
else
return 0;
case SF_SET_PENDING:
- if(dyn->insts[ninst].f_exit.pending!=SF_SET
- && dyn->insts[ninst].f_exit.pending!=SF_SET_PENDING
- && dyn->insts[ninst].f_exit.pending!=SF_PENDING)
- return 1;
- else
+ if(dyn->insts[ninst].f_exit.pending==SF_SET_PENDING)
return 0;
+ return 1;
case SF_PENDING:
- if(dyn->insts[ninst].f_exit.pending!=SF_SET
- && dyn->insts[ninst].f_exit.pending!=SF_SET_PENDING
- && dyn->insts[ninst].f_exit.pending!=SF_PENDING)
- return 1;
- else
- return (dyn->insts[jmp].f_entry.dfnone == dyn->insts[ninst].f_exit.dfnone)?0:1;
+ if(dyn->insts[ninst].f_exit.pending==SF_PENDING || dyn->insts[ninst].f_exit.pending==SF_SET_PENDING)
+ return 0;
+ return (dyn->insts[jmp].f_entry.dfnone == dyn->insts[ninst].f_exit.dfnone)?0:1;
}
- if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone)
- return 1;
return 0;
}
@@ -451,6 +476,12 @@ uintptr_t fakeed(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nexto
}
return addr;
}
+// return Ib on a mod/rm opcode without emiting anything
+uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nextop)
+{
+ addr = fakeed(dyn, addr, ninst, nextop);
+ return F8;
+}
#undef F8
int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn)
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index ed6d0f7..6e7fc46 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -46,7 +46,9 @@ void native_clflush(x64emu_t* emu, void* p);
void native_ud(x64emu_t* emu);
void native_priv(x64emu_t* emu);
void native_singlestep(x64emu_t* emu);
+void native_int3(x64emu_t* emu);
void native_int(x64emu_t* emu, int num);
+void native_div0(x64emu_t* emu);
// Caches transformation (for loops) // Specific, need to be written par backend
int CacheNeedsTransform(dynarec_native_t* dyn, int i1);
@@ -57,6 +59,8 @@ int getNominalPred(dynarec_native_t* dyn, int ninst);
// Do the GETED, but don't emit anything...
uintptr_t fakeed(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);
+// return Ib on a mod/rm opcode without emiting anything
+uint8_t geted_ib(dynarec_native_t* dyn, uintptr_t addr, int ninst, uint8_t nextop);
// Is what pointed at addr a native call? And if yes, to what function?
int isNativeCall(dynarec_native_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn);
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index f5ee250..5686e32 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -77,6 +77,11 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
dyn->last_ip = 0; // reset IP if some jump are coming here
fpu_propagate_stack(dyn, ninst);
NEW_INST;
+ #if STEP == 0
+ if(ninst && dyn->insts[ninst-1].x64.barrier_next) {
+ BARRIER(dyn->insts[ninst-1].x64.barrier_next);
+ }
+ #endif
if(!ninst) {
GOTEST(x1, x2);
}
@@ -88,17 +93,17 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
if(box64_dynarec_test) {
MESSAGE(LOG_DUMP, "TEST INIT ----\n");
fpu_reflectcache(dyn, ninst, x1, x2, x3);
- GO_TRACE(x64test_init, 1);
+ GO_TRACE(x64test_init, 1, x5);
fpu_unreflectcache(dyn, ninst, x1, x2, x3);
MESSAGE(LOG_DUMP, "----------\n");
}
#ifdef HAVE_TRACE
else if(my_context->dec && box64_dynarec_trace) {
- if((trace_end == 0)
+ if((trace_end == 0)
|| ((ip >= trace_start) && (ip < trace_end))) {
MESSAGE(LOG_DUMP, "TRACE ----\n");
fpu_reflectcache(dyn, ninst, x1, x2, x3);
- GO_TRACE(PrintTrace, 1);
+ GO_TRACE(PrintTrace, 1, x5);
fpu_unreflectcache(dyn, ninst, x1, x2, x3);
MESSAGE(LOG_DUMP, "----------\n");
}
@@ -107,12 +112,13 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
rep = 0;
uint8_t pk = PK(0);
- while((pk==0xF2) || (pk==0xF3)) {
- rep = pk-0xF1;
- ++addr;
- pk = PK(0);
- }
- while(pk==0x3E || pk==0x26) { //Branch Taken Hint ignored, same for ES: prefix
+ while((pk==0xF2) || (pk==0xF3) || (pk==0x3E) || (pk==0x26)) {
+ switch(pk) {
+ case 0xF2: rep = 1; break;
+ case 0xF3: rep = 2; break;
+ case 0x3E:
+ case 0x26: /* ignored */ break;
+ }
++addr;
pk = PK(0);
}
@@ -177,7 +183,9 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
if(dyn->forward) {
if(dyn->forward_to == addr && !need_epilog) {
// we made it!
- if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Forward extend block for %d bytes %p -> %p\n", dyn->forward_to-dyn->forward, (void*)dyn->forward, (void*)dyn->forward_to);
+ if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Forward extend block for %d bytes %s%p -> %p\n", dyn->forward_to-dyn->forward, dyn->insts[dyn->forward_ninst].x64.has_callret?"(opt. call) ":"", (void*)dyn->forward, (void*)dyn->forward_to);
+ if(dyn->insts[dyn->forward_ninst].x64.has_callret && !dyn->insts[dyn->forward_ninst].x64.has_next)
+ dyn->insts[dyn->forward_ninst].x64.has_next = 1; // this block actually continue
dyn->forward = 0;
dyn->forward_to = 0;
dyn->forward_size = 0;
@@ -200,18 +208,18 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
if(*(uint32_t*)addr!=0) { // check if need to continue (but is next 4 bytes are 0, stop)
uintptr_t next = get_closest_next(dyn, addr);
if(next && (
- (((next-addr)<15) && is_nops(dyn, addr, next-addr))
+ (((next-addr)<15) && is_nops(dyn, addr, next-addr))
/*||(((next-addr)<30) && is_instructions(dyn, addr, next-addr))*/ ))
{
ok = 1;
- // need to find back that instruction to copy the caches, as previous version cannot be used anymore
- reset_n = -2;
- for(int ii=0; ii<ninst; ++ii)
- if(dyn->insts[ii].x64.jmp == next) {
- reset_n = ii;
- ii=ninst;
- }
- if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Extend block %p, %p -> %p (ninst=%d, jump from %d)\n", dyn, (void*)addr, (void*)next, ninst, reset_n);
+ if(dyn->insts[ninst].x64.has_callret && !dyn->insts[ninst].x64.has_next) {
+ dyn->insts[ninst].x64.has_next = 1; // this block actually continue
+ } else {
+ // need to find back that instruction to copy the caches, as previous version cannot be used anymore
+ // and pred table is not ready yet
+ reset_n = get_first_jump(dyn, next);
+ }
+ if(box64_dynarec_dump) dynarec_log(LOG_NONE, "Extend block %p, %s%p -> %p (ninst=%d, jump from %d)\n", dyn, dyn->insts[ninst].x64.has_callret?"(opt. call) ":"", (void*)addr, (void*)next, ninst, dyn->insts[ninst].x64.has_callret?ninst:reset_n);
} else if(next && (next-addr)<box64_dynarec_forward && (getProtection(next)&PROT_READ)/*box64_dynarec_bigblock>=stopblock*/) {
if(!((box64_dynarec_bigblock<stopblock) && !isJumpTableDefault64((void*)next))) {
if(dyn->forward) {
@@ -232,7 +240,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
}
#endif
if(ok<0) {
- ok = 0; need_epilog=1;
+ ok = 0; need_epilog=1;
#if STEP == 0
if(ninst) {
--ninst;
@@ -256,7 +264,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
}
++ninst;
#if STEP == 0
- if(ok && (((box64_dynarec_bigblock<stopblock) && !isJumpTableDefault64((void*)addr))
+ if(ok && (((box64_dynarec_bigblock<stopblock) && !isJumpTableDefault64((void*)addr))
|| (addr>=box64_nodynarec_start && addr<box64_nodynarec_end)))
#else
if(ok && (ninst==dyn->size))
diff --git a/src/dynarec/dynarec_private.h b/src/dynarec/dynarec_private.h
index 0ab21df..8692070 100644
--- a/src/dynarec/dynarec_private.h
+++ b/src/dynarec/dynarec_private.h
@@ -33,6 +33,8 @@ typedef struct instruction_x64_s {
uint8_t jmp_cond; // 1 of conditionnal jump
uint8_t has_next; // does this opcode can continue to the next?
uint8_t barrier; // next instruction is a jump point, so no optim allowed
+ uint8_t barrier_next; // next instruction needs a barrier
+ uint8_t has_callret; // this instruction have an optimised call setup
uint8_t state_flags;// One of SF_XXX state
uint8_t use_flags; // 0 or combination of X_?F
uint8_t set_flags; // 0 or combination of X_?F
diff --git a/src/dynarec/native_lock.h b/src/dynarec/native_lock.h
index dd2f3b6..70a8eaa 100644
--- a/src/dynarec/native_lock.h
+++ b/src/dynarec/native_lock.h
@@ -28,6 +28,10 @@
#define native_lock_incif0(A) arm64_lock_incif0(A)
#define native_lock_decifnot0(A) arm64_lock_decifnot0(A)
#define native_lock_store(A, B) arm64_lock_store(A, B)
+#define native_lock_store_dd(A, B) arm64_lock_store_dd(A, B)
+#define native_lock_get_b(A) arm64_lock_get_b(A)
+#define native_lock_get_d(A) arm64_lock_get_d(A)
+#define native_lock_get_dd(A) arm64_lock_get_dd(A)
#elif defined(RV64)
#include "rv64/rv64_lock.h"
@@ -50,6 +54,7 @@
#define native_lock_incif0(A) rv64_lock_incif0(A)
#define native_lock_decifnot0(A) rv64_lock_decifnot0(A)
#define native_lock_store(A, B) rv64_lock_store(A, B)
+#define native_lock_store_dd(A, B) rv64_lock_store_dd(A, B)
#define native_lock_cas_d(A, B, C) rv64_lock_cas_d(A, B, C)
#define native_lock_cas_dd(A, B, C) rv64_lock_cas_dd(A, B, C)
@@ -68,6 +73,9 @@
// there is no atomic move on 16bytes, so faking it
#define native_lock_read_dq(A, B, C) *A=tmpcas=((uint64_t*)(C))[0]; *B=((uint64_t*)(C))[1];
#define native_lock_write_dq(A, B, C) rv64_lock_cas_dq(C, A, tmpcas, B);
+#define native_lock_get_b(A) rv64_lock_get_b(A)
+#define native_lock_get_d(A) rv64_lock_get_d(A)
+#define native_lock_get_dd(A) rv64_lock_get_dd(A)
#else
#error Unsupported architecture
diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c
index 4971849..8674eca 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_0.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_0.c
@@ -213,7 +213,7 @@ uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
ANDI(x1, xRAX, 0xff);
emit_adc8c(dyn, ninst, x1, u8, x3, x4, x5, x6);
- ANDI(xRAX, xRAX, -256);
+ ANDI(xRAX, xRAX, ~0xff);
OR(xRAX, xRAX, x1);
break;
case 0x15:
diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c
index 54ca28f..be17f15 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_1.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_1.c
@@ -172,7 +172,10 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
case 0x67:
- addr = dynarec64_67(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ if(rex.is32bits)
+ addr = dynarec64_67_32(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ else
+ addr = dynarec64_67(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
case 0x68:
INST_NAME("PUSH Id");
@@ -260,6 +263,31 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
}
break;
+ case 0x6C:
+ case 0x6D:
+ INST_NAME(opcode == 0x6C ? "INSB" : "INSD");
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ GETIP(ip);
+ STORE_XEMU_CALL(x3);
+ CALL(native_priv, -1);
+ LOAD_XEMU_CALL();
+ jump_to_epilog(dyn, 0, xRIP, ninst);
+ *need_epilog = 0;
+ *ok = 0;
+ break;
+ case 0x6E:
+ case 0x6F:
+ INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD");
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ GETIP(ip);
+ STORE_XEMU_CALL(x3);
+ CALL(native_priv, -1);
+ LOAD_XEMU_CALL();
+ jump_to_epilog(dyn, 0, xRIP, ninst);
+ *need_epilog = 0;
+ *ok = 0;
+ break;
+
#define GO(GETFLAGS, NO, YES, F) \
READFLAGS(F); \
i8 = F8S; \
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 20333f9..bea16d2 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -418,7 +418,7 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LHU(x1, ed, fixedaddress);
ed = x1;
}
- SW(ed, xEmu, offsetof(x64emu_t, segs[(nextop&0x38)>>3]));
+ SH(ed, xEmu, offsetof(x64emu_t, segs[(nextop&0x38)>>3]));
SW(xZR, xEmu, offsetof(x64emu_t, segs_serial[(nextop&0x38)>>3]));
break;
case 0x8F:
@@ -499,15 +499,24 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
if(box64_wine) { // should this be done all the time?
ANDI(x1, xFlags, 1 << F_TF);
CBZ_NEXT(x1);
- MOV64x(xRIP, addr);
- STORE_XEMU_CALL();
- CALL(native_singlestep, -1);
- ANDI(xFlags, xFlags, ~(1 << F_TF));
+ // go to epilog, TF should trigger at end of next opcode, so using Interpretor only
+ jump_to_epilog(dyn, addr, 0, ninst);
}
break;
+ case 0x9E:
+ INST_NAME("SAHF");
+ SETFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF, SF_SUBSET);
+ ADDI(x1, xZR, ~0b11010101);
+ AND(xFlags, xFlags, x1);
+ NOT(x1, x1);
+ SRLI(x2, xRAX, 8);
+ AND(x1, x1, x2);
+ OR(xFlags, xFlags, x1);
+ SET_DFNONE();
+ break;
case 0x9F:
INST_NAME("LAHF");
- READFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF);
+ READFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF);
ANDI(x1, xFlags, 0xFF);
SLLI(x1, x1, 8);
MOV64x(x2, 0xffffffffffff00ffLL);
@@ -558,7 +567,7 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
B_NEXT_nocond;
MARK2; // Part with DF==1
LBU(x1, xRSI, 0);
- LBU(x1, xRDI, 0);
+ SB(x1, xRDI, 0);
SUBI(xRSI, xRSI, 1);
SUBI(xRDI, xRDI, 1);
SUBI(xRCX, xRCX, 1);
@@ -646,6 +655,48 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
}
break;
+ case 0xA7:
+ switch (rep) {
+ case 1:
+ case 2:
+ if (rep == 1) { INST_NAME("REPNZ CMPSD"); } else { INST_NAME("REPZ CMPSD"); }
+ MAYSETFLAGS();
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ CBZ_NEXT(xRCX);
+ ANDI(x1, xFlags, 1 << F_DF);
+ BNEZ_MARK2(x1);
+ MARK; // Part with DF==0
+ LDxw(x1, xRSI, 0);
+ ADDI(xRSI, xRSI, rex.w ? 8 : 4);
+ LDxw(x2, xRDI, 0);
+ ADDI(xRDI, xRDI, rex.w ? 8 : 4);
+ SUBI(xRCX, xRCX, 1);
+ if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+ BNEZ_MARK(xRCX);
+ B_MARK3_nocond;
+ MARK2; // Part with DF==1
+ LDxw(x1, xRSI, 0);
+ SUBI(xRSI, xRSI, rex.w ? 8 : 4);
+ LDxw(x2, xRDI, 0);
+ SUBI(xRDI, xRDI, rex.w ? 8 : 4);
+ SUBI(xRCX, xRCX, 1);
+ if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+ BNEZ_MARK2(xRCX);
+ MARK3; // end
+ emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6);
+ break;
+ default:
+ INST_NAME("CMPSD");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ GETDIR(x3, x1, rex.w ? 8 : 4);
+ LDxw(x1, xRSI, 0);
+ LDxw(x2, xRDI, 0);
+ ADD(xRSI, xRSI, x3);
+ ADD(xRDI, xRDI, x3);
+ emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6);
+ break;
+ }
+ break;
case 0xA8:
INST_NAME("TEST AL, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -711,6 +762,28 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
ADD(xRDI, xRDI, x3);
}
break;
+ case 0xAC:
+ if (rep) {
+ DEFAULT;
+ } else {
+ INST_NAME("LODSB");
+ GETDIR(x1, x2, 1);
+ LBU(x2, xRSI, 0);
+ ADD(xRSI, xRSI, x1);
+ ANDI(xRAX, xRAX, ~0xff);
+ OR(xRAX, xRAX, x2);
+ }
+ break;
+ case 0xAD:
+ if (rep) {
+ DEFAULT;
+ } else {
+ INST_NAME("LODSD");
+ GETDIR(x1, x2, rex.w ? 8 : 4);
+ LDxw(xRAX, xRSI, 0);
+ ADD(xRSI, xRSI, x1);
+ }
+ break;
case 0xAE:
switch (rep) {
case 1:
@@ -780,10 +853,9 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("SCASD");
SETFLAGS(X_ALL, SF_SET_PENDING);
GETDIR(x3, x1, rex.w?8:4);
- AND(x1, xRAX, xMASK);
LDxw(x2, xRDI, 0);
ADD(xRDI, xRDI, x3);
- emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6);
+ emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6);
break;
}
break;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index dece35a..ec59707 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -319,7 +319,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
addr+=8+8;
} else {
GETIP(ip+1); // read the 0xCC
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
ADDI(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL();
@@ -360,7 +360,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
NOTEST(x1);
SMEND();
GETIP(addr);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL_S(x86Syscall, -1);
LOAD_XEMU_CALL();
TABLE64(x3, addr); // expected return address
@@ -368,13 +368,13 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LW(x1, xEmu, offsetof(x64emu_t, quit));
BEQ_NEXT(x1, xZR);
MARK;
- LOAD_XEMU_REM();
+ LOAD_XEMU_REM(x3);
jump_to_epilog(dyn, 0, xRIP, ninst);
} else {
INST_NAME("INT n");
SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL(native_priv, -1);
LOAD_XEMU_CALL();
jump_to_epilog(dyn, 0, xRIP, ninst);
@@ -503,6 +503,16 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
WBACK;
if(!wback && !rex.w) ZEROUP(ed);
break;
+ case 2:
+ INST_NAME("RCL Ed, 1");
+ MESSAGE("LOG_DUMP", "Need optimization\n");
+ READFLAGS(X_CF);
+ SETFLAGS(X_OF|X_CF, SF_SET);
+ MOV32w(x2, 1);
+ GETEDW(x4, x1, 0);
+ CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4);
+ WBACK;
+ break;
case 3:
INST_NAME("RCR Ed, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
@@ -604,7 +614,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
case 0xD9:
addr = dynarec64_D9(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
-
+ case 0xDA:
+ addr = dynarec64_DA(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+ break;
case 0xDB:
addr = dynarec64_DB(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
break;
@@ -723,7 +735,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
dyn->last_ip = addr;
} else {
GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
ADDI(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL();
@@ -755,7 +767,6 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
}
// regular call
- //BARRIER_NEXT(1);
if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
BARRIER(BARRIER_FULL);
} else {
@@ -1076,7 +1087,11 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0xFC:
INST_NAME("CLD");
- ANDI(xFlags, xFlags, ~(1<<F_CF));
+ ANDI(xFlags, xFlags, ~(1 << F_DF));
+ break;
+ case 0xFD:
+ INST_NAME("STD");
+ ORI(xFlags, xFlags, 1 << F_DF);
break;
case 0xFE:
nextop = F8;
@@ -1168,12 +1183,12 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("JMP FAR Ed");
READFLAGS(X_PEND);
BARRIER(BARRIER_FLOAT);
- SMREAD()
+ SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 0, 0);
LDxw(x1, wback, 0);
ed = x1;
LHU(x3, wback, rex.w?8:4);
- SW(x3, xEmu, offsetof(x64emu_t, segs[_CS]));
+ SH(x3, xEmu, offsetof(x64emu_t, segs[_CS]));
SW(xZR, xEmu, offsetof(x64emu_t, segs_serial[_CS]));
jump_to_epilog(dyn, 0, ed, ninst);
*need_epilog = 0;
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 199068c..c08083e 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -26,7 +26,8 @@
uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
- (void)ip; (void)need_epilog;
+ (void)ip;
+ (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
@@ -55,15 +56,15 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
MAYUSE(j64);
MAYUSE(cacheupd);
- switch(opcode) {
+ switch (opcode) {
case 0x01:
INST_NAME("FAKE xgetbv");
nextop = F8;
addr = fakeed(dyn, addr, ninst, nextop);
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL(native_ud, -1);
LOAD_XEMU_CALL();
jump_to_epilog(dyn, 0, xRIP, ninst);
@@ -76,7 +77,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
NOTEST(x1);
SMEND();
GETIP(addr);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL_S(x64Syscall, -1);
LOAD_XEMU_CALL();
TABLE64(x3, addr); // expected return address
@@ -84,15 +85,15 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
LW(w1, xEmu, offsetof(x64emu_t, quit));
CBZ_NEXT(w1);
MARK;
- LOAD_XEMU_REM();
+ LOAD_XEMU_REM(x3);
jump_to_epilog(dyn, 0, xRIP, ninst);
break;
case 0x09:
INST_NAME("WBINVD");
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL(native_ud, -1);
LOAD_XEMU_CALL();
jump_to_epilog(dyn, 0, xRIP, ninst);
@@ -102,9 +103,9 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0x0B:
INST_NAME("UD2");
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
+ SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
GETIP(ip);
- STORE_XEMU_CALL();
+ STORE_XEMU_CALL(x3);
CALL(native_ud, -1);
LOAD_XEMU_CALL();
jump_to_epilog(dyn, 0, xRIP, ninst);
@@ -114,13 +115,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0x0D:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 1:
INST_NAME("PREFETCHW");
// nop without Zicbom, Zicbop, Zicboz extensions
FAKEED;
break;
- default: //???
+ default: //???
DEFAULT;
}
break;
@@ -130,31 +131,31 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x3, wback, fixedaddress+0);
- LD(x4, wback, fixedaddress+8);
- SD(x3, gback, gdoffset+0);
- SD(x4, gback, gdoffset+8);
+ LD(x3, wback, fixedaddress + 0);
+ LD(x4, wback, fixedaddress + 8);
+ SD(x3, gback, gdoffset + 0);
+ SD(x4, gback, gdoffset + 8);
break;
case 0x11:
INST_NAME("MOVUPS Ex,Gx");
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x3, gback, gdoffset+0);
- LD(x4, gback, gdoffset+8);
- SD(x3, wback, fixedaddress+0);
- SD(x4, wback, fixedaddress+8);
- if(!MODREG)
+ LD(x3, gback, gdoffset + 0);
+ LD(x4, gback, gdoffset + 8);
+ SD(x3, wback, fixedaddress + 0);
+ SD(x4, wback, fixedaddress + 8);
+ if (!MODREG)
SMWRITE2();
break;
case 0x12:
nextop = F8;
- if(MODREG) {
+ if (MODREG) {
INST_NAME("MOVHLPS Gx,Ex");
GETGX();
GETEX(x2, 0);
- LD(x3, wback, fixedaddress+8);
- SD(x3, gback, gdoffset+0);
+ LD(x3, wback, fixedaddress + 8);
+ SD(x3, gback, gdoffset + 0);
} else {
INST_NAME("MOVLPS Gx,Ex");
GETEXSD(v0, 0);
@@ -167,9 +168,9 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x3, gback, gdoffset+0);
- SD(x3, wback, fixedaddress+0);
- if(!MODREG)
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, wback, fixedaddress + 0);
+ if (!MODREG)
SMWRITE2();
break;
case 0x14:
@@ -177,30 +178,30 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGX();
GETEX(x2, 0);
- LWU(x5, gback, gdoffset+1*4);
- LWU(x3, wback, fixedaddress+0);
- LWU(x4, wback, fixedaddress+4);
- SW(x4, gback, gdoffset+3*4);
- SW(x5, gback, gdoffset+2*4);
- SW(x3, gback, gdoffset+1*4);
+ LWU(x5, gback, gdoffset + 1 * 4);
+ LWU(x3, wback, fixedaddress + 0);
+ LWU(x4, wback, fixedaddress + 4);
+ SW(x4, gback, gdoffset + 3 * 4);
+ SW(x5, gback, gdoffset + 2 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
break;
case 0x15:
INST_NAME("UNPCKHPS Gx,Ex");
nextop = F8;
GETGX();
GETEX(x2, 0);
- LWU(x3, wback, fixedaddress+2*4);
- LWU(x4, wback, fixedaddress+3*4);
- LWU(x5, gback, gdoffset+2*4);
- LWU(x6, gback, gdoffset+3*4);
- SW(x5, gback, gdoffset+0*4);
- SW(x3, gback, gdoffset+1*4);
- SW(x6, gback, gdoffset+2*4);
- SW(x4, gback, gdoffset+3*4);
+ LWU(x3, wback, fixedaddress + 2 * 4);
+ LWU(x4, wback, fixedaddress + 3 * 4);
+ LWU(x5, gback, gdoffset + 2 * 4);
+ LWU(x6, gback, gdoffset + 3 * 4);
+ SW(x5, gback, gdoffset + 0 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
+ SW(x6, gback, gdoffset + 2 * 4);
+ SW(x4, gback, gdoffset + 3 * 4);
break;
case 0x16:
nextop = F8;
- if(MODREG) {
+ if (MODREG) {
INST_NAME("MOVLHPS Gx,Ex");
} else {
INST_NAME("MOVHPS Gx,Ex");
@@ -208,35 +209,35 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
GETGX();
GETEX(x2, 0);
- LD(x4, wback, fixedaddress+0);
- SD(x4, gback, gdoffset+8);
+ LD(x4, wback, fixedaddress + 0);
+ SD(x4, gback, gdoffset + 8);
break;
case 0x17:
INST_NAME("MOVHPS Ex,Gx");
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x4, gback, gdoffset+8);
- SD(x4, wback, fixedaddress+0);
- if(!MODREG)
+ LD(x4, gback, gdoffset + 8);
+ SD(x4, wback, fixedaddress + 0);
+ if (!MODREG)
SMWRITE2();
break;
case 0x18:
nextop = F8;
- if((nextop&0xC0)==0xC0) {
+ if ((nextop & 0xC0) == 0xC0) {
INST_NAME("NOP (multibyte)");
} else
- switch((nextop>>3)&7) {
- case 0:
- case 1:
- case 2:
- case 3:
- INST_NAME("PREFETCHh Ed");
- FAKEED;
- break;
- default:
- INST_NAME("NOP (multibyte)");
- FAKEED;
+ switch ((nextop >> 3) & 7) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ INST_NAME("PREFETCHh Ed");
+ FAKEED;
+ break;
+ default:
+ INST_NAME("NOP (multibyte)");
+ FAKEED;
}
break;
@@ -259,24 +260,87 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETGX();
GETEX(x2, 0);
SSE_LOOP_MV_Q2(x3);
- if(!MODREG)
+ if (!MODREG)
SMWRITE2();
break;
-
+ case 0x2A:
+ INST_NAME("CVTPI2PS Gx,Em");
+ nextop = F8;
+ GETGX();
+ GETEM(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ u8 = sse_setround(dyn, ninst, x4, x5);
+ for (int i = 0; i < 2; ++i) {
+ LW(x3, wback, fixedaddress + i * 4);
+ FCVTSW(d0, x3, RD_DYN);
+ FSW(d0, gback, gdoffset + i * 4);
+ }
+ x87_restoreround(dyn, ninst, u8);
+ break;
case 0x2B:
INST_NAME("MOVNTPS Ex,Gx");
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x3, gback, gdoffset+0);
- LD(x4, gback, gdoffset+8);
- SD(x3, wback, fixedaddress+0);
- SD(x4, wback, fixedaddress+8);
+ LD(x3, gback, gdoffset + 0);
+ LD(x4, gback, gdoffset + 8);
+ SD(x3, wback, fixedaddress + 0);
+ SD(x4, wback, fixedaddress + 8);
+ break;
+ case 0x2C:
+ INST_NAME("CVTTPS2PI Gm,Ex");
+ nextop = F8;
+ GETGM();
+ GETEX(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ for (int i = 0; i < 2; ++i) {
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
+ }
+ FLW(d0, wback, fixedaddress + i * 4);
+ FCVTWS(x1, d0, RD_RTZ);
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
+ BEQ_MARKi(x5, xZR, i);
+ MOV32w(x1, 0x80000000);
+ MARKi(i);
+ }
+ SW(x1, gback, gdoffset + i * 4);
+ }
+ break;
+ case 0x2D:
+ INST_NAME("CVTPS2PI Gm, Ex");
+ nextop = F8;
+ GETGM();
+ GETEX(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ u8 = sse_setround(dyn, ninst, x6, x4);
+ for (int i = 0; i < 2; ++i) {
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
+ }
+ FLW(d0, wback, fixedaddress + i * 4);
+ FCVTWS(x1, d0, RD_DYN);
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
+ BEQ_MARKi(x5, xZR, i);
+ MOV32w(x1, 0x80000000);
+ MARKi(i);
+ }
+ SW(x1, gback, gdoffset + i * 4);
+ }
+ x87_restoreround(dyn, ninst, u8);
break;
case 0x2E:
// no special check...
case 0x2F:
- if(opcode==0x2F) {INST_NAME("COMISS Gx, Ex");} else {INST_NAME("UCOMISS Gx, Ex");}
+ if (opcode == 0x2F) {
+ INST_NAME("COMISS Gx, Ex");
+ } else {
+ INST_NAME("UCOMISS Gx, Ex");
+ }
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE();
nextop = F8;
@@ -284,160 +348,61 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEXSS(v0, 0);
CLEAR_FLAGS();
// if isnan(d0) || isnan(v0)
- IFX(X_ZF | X_PF | X_CF) {
+ IFX(X_ZF | X_PF | X_CF)
+ {
FEQS(x3, d0, d0);
FEQS(x2, v0, v0);
AND(x2, x2, x3);
BNE_MARK(x2, xZR);
- ORI(xFlags, xFlags, (1<<F_ZF) | (1<<F_PF) | (1<<F_CF));
+ ORI(xFlags, xFlags, (1 << F_ZF) | (1 << F_PF) | (1 << F_CF));
B_NEXT_nocond;
}
MARK;
// else if isless(d0, v0)
- IFX(X_CF) {
+ IFX(X_CF)
+ {
FLTS(x2, d0, v0);
BEQ_MARK2(x2, xZR);
- ORI(xFlags, xFlags, 1<<F_CF);
+ ORI(xFlags, xFlags, 1 << F_CF);
B_NEXT_nocond;
}
MARK2;
// else if d0 == v0
- IFX(X_ZF) {
+ IFX(X_ZF)
+ {
FEQS(x2, d0, v0);
CBZ_NEXT(x2);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
}
break;
case 0x31:
INST_NAME("RDTSC");
NOTEST(x1);
MESSAGE(LOG_DUMP, "Need Optimization\n");
- CALL(ReadTSC, x3); // will return the u64 in x3
+ CALL(ReadTSC, x3); // will return the u64 in x3
SRLI(xRDX, x3, 32);
- AND(xRAX, x3, 32); // wipe upper part
+ AND(xRAX, x3, 32); // wipe upper part
break;
case 0x38:
- //SSE3
- nextop=F8;
- switch(nextop) {
+ // SSE3
+ nextop = F8;
+ switch (nextop) {
case 0xF0:
INST_NAME("MOVBE Gd, Ed");
- nextop=F8;
+ nextop = F8;
GETGD;
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
LDxw(gd, ed, fixedaddress);
- if (rv64_zbb) {
- REV8(gd, gd);
- if (!rex.w) {
- SRLI(gd, gd, 32);
- }
- } else {
- if (rex.w) {
- MOV_U12(x2, 0xff);
- SLLI(x1, gd, 56);
- SRLI(x3, gd, 56);
- SRLI(x4, gd, 40);
- SLLI(x2, x2, 8);
- AND(x4, x4, x2);
- OR(x1, x1, x3);
- OR(x1, x1, x4);
- SLLI(x3, gd, 40);
- SLLI(x4, x2, 40);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
-
- SRLI(x3, gd, 24);
- SLLI(x4, x2, 8);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
- SLLI(x3, gd, 24);
- SLLI(x4, x2, 32);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
-
- SRLI(x3, gd, 8);
- SLLI(x4, x2, 16);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
- SLLI(x3, gd, 8);
- SLLI(x4, x2, 24);
- AND(x3, x3, x4);
- OR(gd, x1, x3);
- } else {
- MOV_U12(x2, 0xff);
- SLLIW(x2, x2, 8);
- SLLIW(x1, gd, 24);
- SRLIW(x3, gd, 24);
- SRLIW(x4, gd, 8);
- AND(x4, x4, x2);
- OR(x1, x1, x3);
- OR(x1, x1, x4);
- SLLIW(gd, gd, 8);
- LUI(x2, 0xff0);
- AND(gd, gd, x2);
- OR(gd, gd, x1);
- }
- }
+ REV8xw(gd, gd, x1, x2, x3, x4);
break;
case 0xF1:
INST_NAME("MOVBE Ed, Gd");
- nextop=F8;
+ nextop = F8;
GETGD;
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
- if (rv64_zbb) {
- REV8(x1, gd);
- if (!rex.w) {
- SRLI(x1, x1, 32);
- }
- } else {
- if (rex.w) {
- MOV_U12(x2, 0xff);
- SLLI(x1, gd, 56);
- SRLI(x3, gd, 56);
- SRLI(x4, gd, 40);
- SLLI(x2, x2, 8);
- AND(x4, x4, x2);
- OR(x1, x1, x3);
- OR(x1, x1, x4);
- SLLI(x3, gd, 40);
- SLLI(x4, x2, 40);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
-
- SRLI(x3, gd, 24);
- SLLI(x4, x2, 8);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
- SLLI(x3, gd, 24);
- SLLI(x4, x2, 32);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
-
- SRLI(x3, gd, 8);
- SLLI(x4, x2, 16);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
- SLLI(x3, gd, 8);
- SLLI(x4, x2, 24);
- AND(x3, x3, x4);
- OR(x1, x1, x3);
- } else {
- MOV_U12(x2, 0xff);
- SLLIW(x2, x2, 8);
- SLLIW(x1, gd, 24);
- SRLIW(x3, gd, 24);
- SRLIW(x4, gd, 8);
- AND(x4, x4, x2);
- OR(x1, x1, x3);
- OR(x1, x1, x4);
- SLLIW(x3, gd, 8);
- LUI(x2, 0xff0);
- AND(x3, x3, x2);
- OR(x1, x1, x3);
- }
- }
+ REV8xw(x1, gd, x1, x2, x3, x4);
SDxw(x1, wback, fixedaddress);
break;
default:
@@ -445,34 +410,34 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
break;
- #define GO(GETFLAGS, NO, YES, F) \
- READFLAGS(F); \
- GETFLAGS; \
- nextop=F8; \
- GETGD; \
- if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- B##NO(x1, 8); \
- MV(gd, ed); \
- } else { \
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \
- B##NO(x1, 8); \
- LDxw(gd, ed, fixedaddress); \
- } \
- if(!rex.w) ZEROUP(gd);
+#define GO(GETFLAGS, NO, YES, F) \
+ READFLAGS(F); \
+ GETFLAGS; \
+ nextop = F8; \
+ GETGD; \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ B##NO(x1, 8); \
+ MV(gd, ed); \
+ } else { \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \
+ B##NO(x1, 8); \
+ LDxw(gd, ed, fixedaddress); \
+ } \
+ if (!rex.w) ZEROUP(gd);
- GOCOND(0x40, "CMOV", "Gd, Ed");
- #undef GO
+ GOCOND(0x40, "CMOV", "Gd, Ed");
+#undef GO
case 0x50:
INST_NAME("MOVMSKPS Gd, Ex");
nextop = F8;
GETGD;
GETEX(x1, 0);
XOR(gd, gd, gd);
- for(int i=0; i<4; ++i) {
- LWU(x2, wback, fixedaddress+i*4);
- SRLI(x2, x2, 31-i);
- if (i>0) ANDI(x2, x2, 1<<i);
+ for (int i = 0; i < 4; ++i) {
+ LWU(x2, wback, fixedaddress + i * 4);
+ SRLI(x2, x2, 31 - i);
+ if (i > 0) ANDI(x2, x2, 1 << i);
OR(gd, gd, x2);
}
break;
@@ -482,10 +447,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETGX();
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
- FLW(d0, wback, fixedaddress+4*i);
+ for (int i = 0; i < 4; ++i) {
+ FLW(d0, wback, fixedaddress + 4 * i);
FSQRTS(d0, d0);
- FSW(d0, gback, gdoffset+4*i);
+ FSW(d0, gback, gdoffset + 4 * i);
}
break;
case 0x52:
@@ -502,23 +467,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
if (!box64_dynarec_fastnan) {
FCVTSW(v0, xZR, RD_DYN);
}
- for(int i=0; i<4; ++i) {
- FLW(s0, wback, fixedaddress+i*4);
+ for (int i = 0; i < 4; ++i) {
+ FLW(s0, wback, fixedaddress + i * 4);
if (!box64_dynarec_fastnan) {
FLES(x3, v0, s0); // s0 >= 0.0f?
- BNEZ(x3, 6*4);
+ BNEZ(x3, 6 * 4);
FEQS(x3, s0, s0); // isnan(s0)?
- BEQZ(x3, 2*4);
+ BEQZ(x3, 2 * 4);
// s0 is negative, so generate a NaN
FDIVS(s0, s1, v0);
// s0 is a NaN, just copy it
- FSW(s0, gback, gdoffset+i*4);
- J(4*4);
+ FSW(s0, gback, gdoffset + i * 4);
+ J(4 * 4);
// do regular computation
}
FSQRTS(s0, s0);
FDIVS(s0, s1, s0);
- FSW(s0, gback, gdoffset+i*4);
+ FSW(s0, gback, gdoffset + i * 4);
}
break;
case 0x53:
@@ -530,17 +495,17 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
d1 = fpu_get_scratch(dyn);
LUI(x3, 0x3f800);
FMVWX(d0, x3); // 1.0f
- for(int i=0; i<4; ++i) {
- FLW(d1, wback, fixedaddress+4*i);
+ for (int i = 0; i < 4; ++i) {
+ FLW(d1, wback, fixedaddress + 4 * i);
FDIVS(d1, d0, d1);
- FSW(d1, gback, gdoffset+4*i);
+ FSW(d1, gback, gdoffset + 4 * i);
}
break;
case 0x54:
INST_NAME("ANDPS Gx, Ex");
nextop = F8;
- gd = ((nextop&0x38)>>3)+(rex.r<<3);
- if(!(MODREG && gd==(nextop&7)+(rex.b<<3))) {
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3);
+ if (!(MODREG && gd == (nextop & 7) + (rex.b << 3))) {
GETGX();
GETEX(x2, 0);
SSE_LOOP_Q(x3, x4, AND(x3, x3, x4));
@@ -556,8 +521,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0x56:
INST_NAME("ORPS Gx, Ex");
nextop = F8;
- gd = ((nextop&0x38)>>3)+(rex.r<<3);
- if(!(MODREG && gd==(nextop&7)+(rex.b<<3))) {
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3);
+ if (!(MODREG && gd == (nextop & 7) + (rex.b << 3))) {
GETGX();
GETEX(x2, 0);
SSE_LOOP_Q(x3, x4, OR(x3, x3, x4));
@@ -566,13 +531,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0x57:
INST_NAME("XORPS Gx, Ex");
nextop = F8;
- //TODO: it might be possible to check if SS or SD are used and not purge them to optimize a bit
+ // TODO: it might be possible to check if SS or SD are used and not purge them to optimize a bit
GETGX();
- if(MODREG && gd==(nextop&7)+(rex.b<<3))
- {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// just zero dest
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
} else {
GETEX(x2, 0);
SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
@@ -585,12 +549,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->f[i] += EX->f[i];
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
FADDS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
break;
case 0x59:
@@ -600,12 +564,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->f[i] *= EX->f[i];
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
FMULS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
break;
case 0x5A:
@@ -616,11 +580,11 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
FLW(s0, wback, fixedaddress);
- FLW(s1, wback, fixedaddress+4);
+ FLW(s1, wback, fixedaddress + 4);
FCVTDS(s0, s0);
FCVTDS(s1, s1);
- FSD(s0, gback, gdoffset+0);
- FSD(s1, gback, gdoffset+8);
+ FSD(s0, gback, gdoffset + 0);
+ FSD(s1, gback, gdoffset + 8);
break;
case 0x5B:
INST_NAME("CVTDQ2PS Gx, Ex");
@@ -628,10 +592,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETGX();
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
- for (int i=0; i<4; ++i) {
- LW(x3, wback, fixedaddress+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, wback, fixedaddress + i * 4);
FCVTSW(s0, x3, RD_RNE);
- FSW(s0, gback, gdoffset+i*4);
+ FSW(s0, gback, gdoffset + i * 4);
}
break;
case 0x5C:
@@ -641,12 +605,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->f[i] -= EX->f[i];
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
FSUBS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
break;
case 0x5D:
@@ -656,20 +620,20 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
- if(!box64_dynarec_fastnan) {
+ for (int i = 0; i < 4; ++i) {
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
+ if (!box64_dynarec_fastnan) {
FEQS(x3, s0, s0);
FEQS(x4, s1, s1);
AND(x3, x3, x4);
BEQZ(x3, 12);
FLTS(x3, s0, s1);
BEQZ(x3, 8);
- FSW(s0, gback, gdoffset+i*4);
+ FSW(s0, gback, gdoffset + i * 4);
} else {
FMINS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
}
break;
@@ -680,12 +644,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->f[i] /= EX->f[i];
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
FDIVS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
break;
case 0x5F:
@@ -695,20 +659,20 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEX(x2, 0);
s0 = fpu_get_scratch(dyn);
s1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
- FLW(s0, wback, fixedaddress+i*4);
- FLW(s1, gback, gdoffset+i*4);
- if(!box64_dynarec_fastnan) {
+ for (int i = 0; i < 4; ++i) {
+ FLW(s0, wback, fixedaddress + i * 4);
+ FLW(s1, gback, gdoffset + i * 4);
+ if (!box64_dynarec_fastnan) {
FEQS(x3, s0, s0);
FEQS(x4, s1, s1);
AND(x3, x3, x4);
BEQZ(x3, 12);
FLTS(x3, s1, s0);
BEQZ(x3, 8);
- FSW(s0, gback, gdoffset+i*4);
+ FSW(s0, gback, gdoffset + i * 4);
} else {
FMAXS(s1, s1, s0);
- FSW(s1, gback, gdoffset+i*4);
+ FSW(s1, gback, gdoffset + i * 4);
}
}
break;
@@ -716,23 +680,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("PUNPCKLBW Gm,Em");
nextop = F8;
GETGM();
- for(int i=3; i>0; --i) { // 0 is untouched
+ for (int i = 3; i > 0; --i) { // 0 is untouched
// GX->ub[2 * i] = GX->ub[i];
- LBU(x3, gback, gdoffset+i);
- SB(x3, gback, gdoffset+2*i);
+ LBU(x3, gback, gdoffset + i);
+ SB(x3, gback, gdoffset + 2 * i);
}
- if (MODREG && gd==(nextop&7)) {
- for(int i=0; i<4; ++i) {
+ if (MODREG && gd == (nextop & 7)) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[2 * i + 1] = GX->ub[2 * i];
- LBU(x3, gback, gdoffset+2*i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, gback, gdoffset + 2 * i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
} else {
GETEM(x2, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[2 * i + 1] = EX->ub[i];
- LBU(x3, wback, fixedaddress+i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, wback, fixedaddress + i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
}
break;
@@ -742,14 +706,14 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETGM();
GETEM(x2, 0);
// GM->uw[3] = EM->uw[1];
- LHU(x3, wback, fixedaddress+2*1);
- SH(x3, gback, gdoffset+2*3);
+ LHU(x3, wback, fixedaddress + 2 * 1);
+ SH(x3, gback, gdoffset + 2 * 3);
// GM->uw[2] = GM->uw[1];
- LHU(x3, gback, gdoffset+2*1);
- SH(x3, gback, gdoffset+2*2);
+ LHU(x3, gback, gdoffset + 2 * 1);
+ SH(x3, gback, gdoffset + 2 * 2);
// GM->uw[1] = EM->uw[0];
- LHU(x3, wback, fixedaddress+2*0);
- SH(x3, gback, gdoffset+2*1);
+ LHU(x3, wback, fixedaddress + 2 * 0);
+ SH(x3, gback, gdoffset + 2 * 1);
break;
case 0x62:
INST_NAME("PUNPCKLDQ Gm, Em");
@@ -758,38 +722,38 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEM(x2, 0);
// GM->ud[1] = EM->ud[0];
LWU(x3, wback, fixedaddress);
- SW(x3, gback, gdoffset+4*1);
+ SW(x3, gback, gdoffset + 4 * 1);
break;
case 0x67:
INST_NAME("PACKUSWB Gm, Em");
nextop = F8;
GETGM();
ADDI(x5, xZR, 0xFF);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[i] = (GX->sw[i]<0)?0:((GX->sw[i]>0xff)?0xff:GX->sw[i]);
- LH(x3, gback, gdoffset+i*2);
+ LH(x3, gback, gdoffset + i * 2);
BGE(x5, x3, 8);
ADDI(x3, xZR, 0xFF);
NOT(x4, x3);
SRAI(x4, x4, 63);
AND(x3, x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
- if (MODREG && gd==(nextop&7)) {
+ if (MODREG && gd == (nextop & 7)) {
// GM->ud[1] = GM->ud[0];
- LW(x3, gback, gdoffset+0*4);
- SW(x3, gback, gdoffset+1*4);
+ LW(x3, gback, gdoffset + 0 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
} else {
GETEM(x1, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[4+i] = (EX->sw[i]<0)?0:((EX->sw[i]>0xff)?0xff:EX->sw[i]);
- LH(x3, wback, fixedaddress+i*2);
+ LH(x3, wback, fixedaddress + i * 2);
BGE(x5, x3, 8);
ADDI(x3, xZR, 0xFF);
NOT(x4, x3);
SRAI(x4, x4, 63);
AND(x3, x3, x4);
- SB(x3, gback, gdoffset+4+i);
+ SB(x3, gback, gdoffset + 4 + i);
}
}
break;
@@ -797,23 +761,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("PUNPCKHBW Gm,Em");
nextop = F8;
GETGM();
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[2 * i] = GX->ub[i + 4];
- LBU(x3, gback, gdoffset+i+4);
- SB(x3, gback, gdoffset+2*i);
+ LBU(x3, gback, gdoffset + i + 4);
+ SB(x3, gback, gdoffset + 2 * i);
}
- if (MODREG && gd==(nextop&7)) {
- for(int i=0; i<4; ++i) {
+ if (MODREG && gd == (nextop & 7)) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[2 * i + 1] = GX->ub[2 * i];
- LBU(x3, gback, gdoffset+2*i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, gback, gdoffset + 2 * i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
} else {
GETEM(x2, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->ub[2 * i + 1] = EX->ub[i + 4];
- LBU(x3, wback, fixedaddress+i+4);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, wback, fixedaddress + i + 4);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
}
break;
@@ -821,23 +785,23 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("PUNPCKHWD Gm,Em");
nextop = F8;
GETGM();
- for(int i=0; i<2; ++i) {
+ for (int i = 0; i < 2; ++i) {
// GX->uw[2 * i] = GX->uw[i + 2];
- LHU(x3, gback, gdoffset+(i+2)*2);
- SH(x3, gback, gdoffset+2*i*2);
+ LHU(x3, gback, gdoffset + (i + 2) * 2);
+ SH(x3, gback, gdoffset + 2 * i * 2);
}
- if (MODREG && gd==(nextop&7)) {
- for(int i=0; i<2; ++i) {
+ if (MODREG && gd == (nextop & 7)) {
+ for (int i = 0; i < 2; ++i) {
// GX->uw[2 * i + 1] = GX->uw[2 * i];
- LHU(x3, gback, gdoffset+2*i*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, gback, gdoffset + 2 * i * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
} else {
GETEM(x1, 0);
- for(int i=0; i<2; ++i) {
+ for (int i = 0; i < 2; ++i) {
// GX->uw[2 * i + 1] = EX->uw[i + 2];
- LHU(x3, wback, fixedaddress+(i+2)*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, wback, fixedaddress + (i + 2) * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
}
break;
@@ -847,30 +811,61 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEM(x1, 0);
GETGM();
// GM->ud[0] = GM->ud[1];
- LWU(x3, gback, gdoffset+1*4);
- SW(x3, gback, gdoffset+0*4);
- if (!(MODREG && (gd==ed))) {
+ LWU(x3, gback, gdoffset + 1 * 4);
+ SW(x3, gback, gdoffset + 0 * 4);
+ if (!(MODREG && (gd == ed))) {
// GM->ud[1] = EM->ud[1];
- LWU(x3, wback, fixedaddress+1*4);
- SW(x3, gback, gdoffset+1*4);
+ LWU(x3, wback, fixedaddress + 1 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
+ }
+ break;
+ case 0x6B:
+ INST_NAME("PACKSSDW Gm,Em");
+ nextop = F8;
+ GETGM();
+ for (int i = 0; i < 2; ++i) {
+ // GM->sw[i] = (GM->sd[i]<-32768)?-32768:((GM->sd[i]>32767)?32767:GM->sd[i]);
+ LW(x3, gback, gdoffset + i * 4);
+ LUI(x4, 0xFFFF8); // -32768
+ BGE(x3, x4, 12);
+ SH(x4, gback, gdoffset + i * 2);
+ J(20); // continue
+ LUI(x4, 8); // 32768
+ BLT(x3, x4, 8);
+ ADDIW(x3, x4, -1);
+ SH(x3, gback, gdoffset + i * 2);
+ }
+ if (MODREG && gd == (nextop & 7)) {
+ LWU(x3, gback, gdoffset);
+ SW(x3, gback, gdoffset + 4);
+ } else {
+ GETEM(x1, 0);
+ for (int i = 0; i < 2; ++i) {
+ // GM->sw[2+i] = (EM->sd[i]<-32768)?-32768:((EM->sd[i]>32767)?32767:EM->sd[i]);
+ LW(x3, wback, fixedaddress + i * 4);
+ LUI(x4, 0xFFFF8); // -32768
+ BGE(x3, x4, 12);
+ SH(x4, gback, gdoffset + 4 + i * 2);
+ J(20); // continue
+ LUI(x4, 8); // 32768
+ BLT(x3, x4, 8);
+ ADDIW(x3, x4, -1);
+ SH(x3, gback, gdoffset + 4 + i * 2);
+ }
}
break;
case 0x6E:
INST_NAME("MOVD Gm, Ed");
nextop = F8;
GETGM();
- if(MODREG) {
- ed = xRAX + (nextop&7) + (rex.b<<3);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0);
- if(rex.w) {
- LD(x4, ed, fixedaddress);
- } else {
- LW(x4, ed, fixedaddress);
- }
+ LDxw(x4, ed, fixedaddress);
ed = x4;
}
- if(rex.w) SD(ed, gback, gdoffset+0); else SW(ed, gback, gdoffset+0);
+ SD(ed, gback, gdoffset + 0);
break;
case 0x6F:
INST_NAME("MOVQ Gm, Em");
@@ -878,24 +873,24 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETGM();
GETEM(x2, 0);
LD(x3, wback, fixedaddress);
- SD(x3, gback, gdoffset+0);
+ SD(x3, gback, gdoffset + 0);
break;
case 0x71:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 2:
INST_NAME("PSRLW Em, Ib");
GETEM(x1, 1);
u8 = F8;
- if (u8>15) {
+ if (u8 > 15) {
// just zero dest
SD(xZR, wback, fixedaddress);
- } else if(u8) {
- for (int i=0; i<4; ++i) {
+ } else if (u8) {
+ for (int i = 0; i < 4; ++i) {
// EX->uw[i] >>= u8;
- LHU(x3, wback, fixedaddress+i*2);
+ LHU(x3, wback, fixedaddress + i * 2);
SRLI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -903,13 +898,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("PSRAW Em, Ib");
GETEM(x1, 1);
u8 = F8;
- if(u8>15) u8=15;
- if(u8) {
- for (int i=0; i<4; ++i) {
+ if (u8 > 15) u8 = 15;
+ if (u8) {
+ for (int i = 0; i < 4; ++i) {
// EX->sw[i] >>= u8;
- LH(x3, wback, fixedaddress+i*2);
+ LH(x3, wback, fixedaddress + i * 2);
SRAI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -917,15 +912,15 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("PSLLW Em, Ib");
GETEM(x1, 1);
u8 = F8;
- if (u8>15) {
+ if (u8 > 15) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- } else if(u8) {
- for (int i=0; i<4; ++i) {
+ SD(xZR, wback, fixedaddress + 0);
+ } else if (u8) {
+ for (int i = 0; i < 4; ++i) {
// EX->uw[i] <<= u8;
- LHU(x3, wback, fixedaddress+i*2);
+ LHU(x3, wback, fixedaddress + i * 2);
SLLI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -934,6 +929,94 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
DEFAULT;
}
break;
+ case 0x72:
+ nextop = F8;
+ switch ((nextop >> 3) & 7) {
+ case 2:
+ INST_NAME("PSRLD Em, Ib");
+ GETEM(x4, 1);
+ u8 = F8;
+ if (u8) {
+ if (u8 > 31) {
+ SD(xZR, wback, fixedaddress);
+ } else {
+ LD(x1, wback, fixedaddress);
+ SRLI(x2, x1, 32 + u8);
+ SRLIW(x1, x1, u8);
+ SW(x1, wback, fixedaddress);
+ SW(x2, wback, fixedaddress + 4);
+ }
+ }
+ break;
+ case 4:
+ INST_NAME("PSRAD Em, Ib");
+ GETEM(x4, 1);
+ u8 = F8;
+ if (u8 > 31) u8 = 31;
+ if (u8) {
+ LD(x1, wback, fixedaddress);
+ SRAI(x2, x1, 32 + u8);
+ SRAIW(x1, x1, u8);
+ SW(x1, wback, fixedaddress);
+ SW(x2, wback, fixedaddress + 4);
+ }
+ break;
+ case 6:
+ INST_NAME("PSLLD Em, Ib");
+ GETEM(x4, 1);
+ u8 = F8;
+ if (u8) {
+ if (u8 > 31) {
+ SD(xZR, wback, fixedaddress);
+ } else {
+ LD(x1, wback, fixedaddress);
+ SRLI(x2, x1, 32);
+ SLLIW(x1, x1, u8);
+ SLLIW(x2, x2, u8);
+ SW(x1, wback, fixedaddress);
+ SW(x2, wback, fixedaddress + 4);
+ }
+ }
+ break;
+ default:
+ DEFAULT;
+ }
+ break;
+ case 0x73:
+ nextop = F8;
+ switch ((nextop >> 3) & 7) {
+ case 2:
+ INST_NAME("PSRLQ Em, Ib");
+ GETEM(x4, 1);
+ u8 = F8;
+ if (u8) {
+ if (u8 > 63) {
+ SD(xZR, wback, fixedaddress);
+ } else if (u8) {
+ LD(x1, wback, fixedaddress);
+ SRLI(x1, x1, u8);
+ SD(x1, wback, fixedaddress);
+ }
+ }
+ break;
+ case 6:
+ INST_NAME("PSLLQ Em, Ib");
+ GETEM(x4, 1);
+ u8 = F8;
+ if (u8) {
+ if (u8 > 63) {
+ SD(xZR, wback, fixedaddress);
+ } else {
+ LD(x1, wback, fixedaddress);
+ SLLI(x1, x1, u8);
+ SD(x1, wback, fixedaddress);
+ }
+ }
+ break;
+ default:
+ DEFAULT;
+ }
+ break;
case 0x75:
INST_NAME("PCMPEQW Gm,Em");
nextop = F8;
@@ -946,76 +1029,90 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
// empty MMX, FPU now usable
mmx_purgecache(dyn, ninst, 0, x1);
/*emu->top = 0;
- emu->fpu_stack = 0;*/ //TODO: Check if something is needed here?
+ emu->fpu_stack = 0;*/
+ // TODO: Check if something is needed here?
+ break;
+ case 0x7E:
+ INST_NAME("MOVD Ed, Gm");
+ nextop = F8;
+ GETGM();
+ if ((nextop & 0xC0) == 0xC0) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ LDxw(ed, gback, gdoffset);
+ } else {
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, 0);
+ LDxw(x1, gback, gdoffset);
+ SDxw(x1, wback, fixedaddress);
+ SMWRITE2();
+ }
break;
case 0x7F:
INST_NAME("MOVQ Em, Gm");
nextop = F8;
GETGM();
GETEM(x2, 0);
- LD(x3, gback, gdoffset+0);
+ LD(x3, gback, gdoffset + 0);
SD(x3, wback, fixedaddress);
break;
- #define GO(GETFLAGS, NO, YES, F) \
- READFLAGS(F); \
- i32_ = F32S; \
- BARRIER(BARRIER_MAYBE); \
- JUMP(addr+i32_, 1); \
- GETFLAGS; \
- if(dyn->insts[ninst].x64.jmp_insts==-1 || \
- CHECK_CACHE()) { \
- /* out of the block */ \
- i32 = dyn->insts[ninst].epilog-(dyn->native_size); \
- B##NO##_safe(x1, i32); \
- if(dyn->insts[ninst].x64.jmp_insts==-1) { \
- if(!(dyn->insts[ninst].x64.barrier&BARRIER_FLOAT)) \
- fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
- jump_to_next(dyn, addr+i32_, 0, ninst); \
- } else { \
- CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
- i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
- B(i32); \
- } \
- } else { \
- /* inside the block */ \
- i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->native_size); \
- B##YES##_safe(x1, i32); \
- }
+#define GO(GETFLAGS, NO, YES, F) \
+ READFLAGS(F); \
+ i32_ = F32S; \
+ BARRIER(BARRIER_MAYBE); \
+ JUMP(addr + i32_, 1); \
+ GETFLAGS; \
+ if (dyn->insts[ninst].x64.jmp_insts == -1 || CHECK_CACHE()) { \
+ /* out of the block */ \
+ i32 = dyn->insts[ninst].epilog - (dyn->native_size); \
+ B##NO##_safe(x1, i32); \
+ if (dyn->insts[ninst].x64.jmp_insts == -1) { \
+ if (!(dyn->insts[ninst].x64.barrier & BARRIER_FLOAT)) \
+ fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \
+ jump_to_next(dyn, addr + i32_, 0, ninst); \
+ } else { \
+ CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \
+ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); \
+ B(i32); \
+ } \
+ } else { \
+ /* inside the block */ \
+ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); \
+ B##YES##_safe(x1, i32); \
+ }
- GOCOND(0x80, "J", "Id");
- #undef GO
+ GOCOND(0x80, "J", "Id");
+#undef GO
- #define GO(GETFLAGS, NO, YES, F) \
- READFLAGS(F); \
- GETFLAGS; \
- nextop=F8; \
- S##YES(x3, x1); \
- if(MODREG) { \
- if(rex.rex) { \
- eb1= xRAX+(nextop&7)+(rex.b<<3); \
- eb2 = 0; \
- } else { \
- ed = (nextop&7); \
- eb2 = (ed>>2)*8; \
- eb1 = xRAX+(ed&3); \
- } \
- if (eb2) { \
- LUI(x1, 0xffff0); \
- ORI(x1, x1, 0xff); \
- AND(eb1, eb1, x1); \
- SLLI(x3, x3, 8); \
- } else { \
- ANDI(eb1, eb1, 0xf00); \
- } \
- OR(eb1, eb1, x3); \
- } else { \
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress,rex, NULL, 1, 0); \
- SB(x3, ed, fixedaddress); \
- SMWRITE(); \
- }
+#define GO(GETFLAGS, NO, YES, F) \
+ READFLAGS(F); \
+ GETFLAGS; \
+ nextop = F8; \
+ S##YES(x3, x1); \
+ if (MODREG) { \
+ if (rex.rex) { \
+ eb1 = xRAX + (nextop & 7) + (rex.b << 3); \
+ eb2 = 0; \
+ } else { \
+ ed = (nextop & 7); \
+ eb2 = (ed >> 2) * 8; \
+ eb1 = xRAX + (ed & 3); \
+ } \
+ if (eb2) { \
+ LUI(x1, 0xffff0); \
+ ORI(x1, x1, 0xff); \
+ AND(eb1, eb1, x1); \
+ SLLI(x3, x3, 8); \
+ } else { \
+ ANDI(eb1, eb1, 0xf00); \
+ } \
+ OR(eb1, eb1, x3); \
+ } else { \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); \
+ SB(x3, ed, fixedaddress); \
+ SMWRITE(); \
+ }
- GOCOND(0x90, "SET", "Eb");
- #undef GO
+ GOCOND(0x90, "SET", "Eb");
+#undef GO
case 0xA2:
INST_NAME("CPUID");
@@ -1032,21 +1129,18 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
nextop = F8;
GETGD;
- if(MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
- SRAIxw(x1, gd, 5+rex.w); // r1 = (gd>>5)
- SLLI(x1, x1, 2+rex.w);
- ADD(x3, wback, x1); //(&ed)+=r1*4;
+ SRAIxw(x1, gd, 5 + rex.w); // r1 = (gd>>5)
+ ADDSL(x3, wback, x1, 2 + rex.w, x1);
LDxw(x1, x3, fixedaddress);
ed = x1;
}
- ANDI(x2, gd, rex.w?0x3f:0x1f);
- SRL(x4, ed, x2);
- ANDI(x4, x4, 1);
- ANDI(xFlags, xFlags, ~1); //F_CF is 1
+ BEXT(x4, ed, gd, x2);
+ ANDI(xFlags, xFlags, ~1); // F_CF is 1
OR(xFlags, xFlags, x4);
break;
case 0xA4:
@@ -1066,31 +1160,25 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGD;
if (MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
wback = 0;
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
- SRAI(x1, gd, 5+rex.w);
- SLLI(x1, x1, 2+rex.w);
- ADD(x3, wback, x1);
+ SRAIxw(x1, gd, 5 + rex.w);
+ ADDSL(x3, wback, x1, 2 + rex.w, x1);
LDxw(x1, x3, fixedaddress);
ed = x1;
wback = x3;
}
- if (rex.w) {
- ANDI(x2, gd, 0x3f);
- } else {
- ANDI(x2, gd, 0x1f);
- }
- SRL(x4, ed, x2);
- ANDI(x4, x4, 1); // F_CF is 1
+ BEXT(x4, ed, gd, x2);
ANDI(xFlags, xFlags, ~1);
OR(xFlags, xFlags, x4);
- ADDI(x3, xZR, 1);
- SLL(x3, x3, x2);
- OR(ed, ed, x3);
- if(wback) {
+ ADDI(x4, xZR, 1);
+ ANDI(x2, gd, rex.w ? 0x3f : 0x1f);
+ SLL(x4, x4, x2);
+ OR(ed, ed, x4);
+ if (wback) {
SDxw(ed, wback, fixedaddress);
SMWRITE();
}
@@ -1102,36 +1190,34 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETED(1);
GETGD;
u8 = F8;
- u8&=(rex.w?0x3f:0x1f);
+ u8 &= (rex.w ? 0x3f : 0x1f);
emit_shrd32c(dyn, ninst, rex, ed, gd, u8, x3, x4);
WBACK;
break;
case 0xAE:
nextop = F8;
- if((nextop&0xF8)==0xE8) {
+ if ((nextop & 0xF8) == 0xE8) {
INST_NAME("LFENCE");
SMDMB();
- } else
- if((nextop&0xF8)==0xF0) {
+ } else if ((nextop & 0xF8) == 0xF0) {
INST_NAME("MFENCE");
SMDMB();
- } else
- if((nextop&0xF8)==0xF8) {
+ } else if ((nextop & 0xF8) == 0xF8) {
INST_NAME("SFENCE");
SMDMB();
} else {
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 0:
INST_NAME("FXSAVE Ed");
MESSAGE(LOG_DUMP, "Need Optimization\n");
SKIPTEST(x1);
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
- if(MODREG) {
+ if (MODREG) {
DEFAULT;
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x3, &fixedaddress, rex, NULL, 0, 0);
- if(ed!=x1) {MV(x1, ed);}
- CALL(rex.w?((void*)fpu_fxsave64):((void*)fpu_fxsave32), -1);
+ if (ed != x1) { MV(x1, ed); }
+ CALL(rex.w ? ((void*)fpu_fxsave64) : ((void*)fpu_fxsave32), -1);
}
break;
case 1:
@@ -1139,19 +1225,19 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
MESSAGE(LOG_DUMP, "Need Optimization\n");
SKIPTEST(x1);
fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
- if(MODREG) {
+ if (MODREG) {
DEFAULT;
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x3, &fixedaddress, rex, NULL, 0, 0);
- if(ed!=x1) {MV(x1, ed);}
- CALL(rex.w?((void*)fpu_fxrstor64):((void*)fpu_fxrstor32), -1);
+ if (ed != x1) { MV(x1, ed); }
+ CALL(rex.w ? ((void*)fpu_fxrstor64) : ((void*)fpu_fxrstor32), -1);
}
break;
case 2:
INST_NAME("LDMXCSR Md");
GETED(0);
SW(ed, xEmu, offsetof(x64emu_t, mxcsr));
- if(box64_sse_flushto0) {
+ if (box64_sse_flushto0) {
// TODO: applyFlushTo0 also needs to add RISC-V support.
}
break;
@@ -1165,7 +1251,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("CLFLUSH Ed");
MESSAGE(LOG_DUMP, "Need Optimization?\n");
addr = geted(dyn, addr, ninst, nextop, &wback, x1, x2, &fixedaddress, rex, NULL, 0, 0);
- if(wback!=A1) {
+ if (wback != A1) {
MV(A1, wback);
}
CALL_(native_clflush, -1, 0);
@@ -1181,26 +1267,32 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGD;
GETED(0);
- if(rex.w) {
+ if (rex.w) {
// 64bits imul
- UFLAG_IF {
+ UFLAG_IF
+ {
MULH(x3, gd, ed);
MUL(gd, gd, ed);
UFLAG_OP1(x3);
UFLAG_RES(gd);
UFLAG_DF(x3, d_imul64);
- } else {
+ }
+ else
+ {
MULxw(gd, gd, ed);
}
} else {
// 32bits imul
- UFLAG_IF {
+ UFLAG_IF
+ {
MUL(gd, gd, ed);
UFLAG_RES(gd);
SRLI(x3, gd, 32);
UFLAG_OP1(x3);
UFLAG_DF(x3, d_imul32);
- } else {
+ }
+ else
+ {
MULxw(gd, gd, ed);
}
SLLI(gd, gd, 32);
@@ -1213,33 +1305,27 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
nextop = F8;
GETGD;
- if(MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
wback = 0;
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
- SRAI(x1, gd, 5+rex.w);
- SLLI(x1, x1, 2+rex.w);
- ADD(x3, wback, x1);
+ SRAIxw(x1, gd, 5 + rex.w);
+ ADDSL(x3, wback, x1, 2 + rex.w, x1);
LDxw(x1, x3, fixedaddress);
ed = x1;
wback = x3;
}
- if (rex.w) {
- ANDI(x2, gd, 0x3f);
- } else {
- ANDI(x2, gd, 0x1f);
- }
- SRL(x4, ed, x2);
- ANDI(x4, x4, 1); // F_CF is 1
+ BEXT(x4, ed, gd, x2); // F_CF is 1
ANDI(xFlags, xFlags, ~1);
OR(xFlags, xFlags, x4);
- ADDI(x5, xZR, 1);
- SLL(x5, x5, x2);
- NOT(x5, x5);
- AND(ed, ed, x5);
- if(wback) {
+ ADDI(x4, xZR, 1);
+ ANDI(x2, gd, rex.w ? 0x3f : 0x1f);
+ SLL(x4, x4, x2);
+ NOT(x4, x4);
+ AND(ed, ed, x4);
+ if (wback) {
SDxw(ed, wback, fixedaddress);
SMWRITE();
}
@@ -1248,14 +1334,14 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("MOVZX Gd, Eb");
nextop = F8;
GETGD;
- if(MODREG) {
- if(rex.rex) {
- eb1 = xRAX+(nextop&7)+(rex.b<<3);
- eb2 = 0; \
+ if (MODREG) {
+ if (rex.rex) {
+ eb1 = xRAX + (nextop & 7) + (rex.b << 3);
+ eb2 = 0;
} else {
- ed = (nextop&7);
- eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
- eb2 = (ed&4)>>2; // L or H
+ ed = (nextop & 7);
+ eb1 = xRAX + (ed & 3); // Ax, Cx, Dx or Bx
+ eb2 = (ed & 4) >> 2; // L or H
}
if (eb2) {
SRLI(gd, eb1, 8);
@@ -1273,8 +1359,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("MOVZX Gd, Ew");
nextop = F8;
GETGD;
- if(MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
ZEXTH(gd, ed);
} else {
SMREAD();
@@ -1284,16 +1370,15 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
break;
case 0xBA:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 4:
INST_NAME("BT Ed, Ib");
SETFLAGS(X_CF, SF_SUBSET);
SET_DFNONE();
GETED(1);
u8 = F8;
- u8&=rex.w?0x3f:0x1f;
- SRLIxw(x3, ed, u8);
- ANDI(x3, x3, 1); // F_CF is 1
+ u8 &= rex.w ? 0x3f : 0x1f;
+ BEXTI(x3, ed, u8); // F_CF is 1
ANDI(xFlags, xFlags, ~1);
OR(xFlags, xFlags, x3);
break;
@@ -1303,19 +1388,19 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
GETED(1);
u8 = F8;
- u8&=(rex.w?0x3f:0x1f);
- ORI(xFlags, xFlags, 1<<F_CF);
+ u8 &= (rex.w ? 0x3f : 0x1f);
+ ORI(xFlags, xFlags, 1 << F_CF);
if (u8 <= 10) {
- ANDI(x6, ed, 1<<u8);
+ ANDI(x6, ed, 1 << u8);
BNE_MARK(x6, xZR);
- ANDI(xFlags, xFlags, ~(1<<F_CF));
- XORI(ed, ed, 1<<u8);
+ ANDI(xFlags, xFlags, ~(1 << F_CF));
+ XORI(ed, ed, 1 << u8);
} else {
ORI(x6, xZR, 1);
SLLI(x6, x6, u8);
AND(x4, ed, x6);
BNE_MARK(x4, xZR);
- ANDI(xFlags, xFlags, ~(1<<F_CF));
+ ANDI(xFlags, xFlags, ~(1 << F_CF));
XOR(ed, ed, x6);
}
if (wback) {
@@ -1330,19 +1415,19 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
GETED(1);
u8 = F8;
- u8&=(rex.w?0x3f:0x1f);
- ANDI(xFlags, xFlags, ~(1<<F_CF));
+ u8 &= (rex.w ? 0x3f : 0x1f);
+ ANDI(xFlags, xFlags, ~(1 << F_CF));
if (u8 <= 10) {
- ANDI(x6, ed, 1<<u8);
+ ANDI(x6, ed, 1 << u8);
BEQ_MARK(x6, xZR);
- ORI(xFlags, xFlags, 1<<F_CF);
- XORI(ed, ed, 1<<u8);
+ ORI(xFlags, xFlags, 1 << F_CF);
+ XORI(ed, ed, 1 << u8);
} else {
ORI(x6, xZR, 1);
SLLI(x6, x6, u8);
AND(x6, ed, x6);
BEQ_MARK(x6, xZR);
- ORI(xFlags, xFlags, 1<<F_CF);
+ ORI(xFlags, xFlags, 1 << F_CF);
XOR(ed, ed, x6);
}
if (wback) {
@@ -1357,9 +1442,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
GETED(1);
u8 = F8;
- u8&=rex.w?0x3f:0x1f;
- SRLIxw(x3, ed, u8);
- ANDI(x3, x3, 1); // F_CF is 1
+ u8 &= rex.w ? 0x3f : 0x1f;
+ BEXTI(x3, ed, u8); // F_CF is 1
ANDI(xFlags, xFlags, ~1);
OR(xFlags, xFlags, x3);
if (u8 <= 10) {
@@ -1368,7 +1452,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
MOV64xw(x3, (1LL << u8));
XOR(ed, ed, x3);
}
- if(wback) {
+ if (wback) {
SDxw(ed, wback, fixedaddress);
SMWRITE();
}
@@ -1384,31 +1468,25 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETGD;
if (MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
wback = 0;
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0);
- SRAI(x1, gd, 5+rex.w);
- SLLI(x1, x1, 2+rex.w);
- ADD(x3, wback, x1);
+ SRAIxw(x1, gd, 5 + rex.w);
+ ADDSL(x3, wback, x1, 2 + rex.w, x1);
LDxw(x1, x3, fixedaddress);
ed = x1;
wback = x3;
}
- if (rex.w) {
- ANDI(x2, gd, 0x3f);
- } else {
- ANDI(x2, gd, 0x1f);
- }
- SRL(x4, ed, x2);
- ANDI(x4, x4, 1); // F_CF is 1
+ BEXT(x4, ed, gd, x2); // F_CF is 1
ANDI(xFlags, xFlags, ~1);
OR(xFlags, xFlags, x4);
- ADDI(x3, xZR, 1);
- SLL(x3, x3, x2);
- XOR(ed, ed, x3);
- if(wback) {
+ ADDI(x4, xZR, 1);
+ ANDI(x2, gd, rex.w ? 0x3f : 0x1f);
+ SLL(x4, x4, x2);
+ XOR(ed, ed, x4);
+ if (wback) {
SDxw(ed, wback, fixedaddress);
SMWRITE();
}
@@ -1420,27 +1498,27 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETED(0);
GETGD;
- if(!rex.w && MODREG) {
+ if (!rex.w && MODREG) {
AND(x4, ed, xMASK);
ed = x4;
}
BNE_MARK(ed, xZR);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
B_NEXT_nocond;
MARK;
- if(rv64_zbb) {
+ if (rv64_zbb) {
CTZxw(gd, ed);
} else {
NEG(x2, ed);
AND(x2, x2, ed);
TABLE64(x3, 0x03f79d71b4ca8b09ULL);
MUL(x2, x2, x3);
- SRLI(x2, x2, 64-6);
+ SRLI(x2, x2, 64 - 6);
TABLE64(x1, (uintptr_t)&deBruijn64tab);
ADD(x1, x1, x2);
LBU(gd, x1, 0);
}
- ANDI(xFlags, xFlags, ~(1<<F_ZF));
+ ANDI(xFlags, xFlags, ~(1 << F_ZF));
break;
case 0xBD:
INST_NAME("BSR Gd, Ed");
@@ -1449,44 +1527,44 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
nextop = F8;
GETED(0);
GETGD;
- if(!rex.w && MODREG) {
+ if (!rex.w && MODREG) {
AND(x4, ed, xMASK);
ed = x4;
}
BNE_MARK(ed, xZR);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
B_NEXT_nocond;
MARK;
- ANDI(xFlags, xFlags, ~(1<<F_ZF));
- if(rv64_zbb) {
- MOV32w(x1, rex.w?63:31);
+ ANDI(xFlags, xFlags, ~(1 << F_ZF));
+ if (rv64_zbb) {
+ MOV32w(x1, rex.w ? 63 : 31);
CLZxw(gd, ed);
SUB(gd, x1, gd);
} else {
- if(ed!=gd)
+ if (ed != gd)
u8 = gd;
else
u8 = x1;
ADDI(u8, xZR, 0);
- if(rex.w) {
+ if (rex.w) {
MV(x2, ed);
SRLI(x3, x2, 32);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
ADDI(u8, u8, 32);
MV(x2, x3);
} else {
AND(x2, ed, xMASK);
}
SRLI(x3, x2, 16);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
ADDI(u8, u8, 16);
MV(x2, x3);
SRLI(x3, x2, 8);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
ADDI(u8, u8, 8);
MV(x2, x3);
SRLI(x3, x2, 4);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
ADDI(u8, u8, 4);
MV(x2, x3);
ANDI(x2, x2, 0b1111);
@@ -1500,31 +1578,31 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
INST_NAME("MOVSX Gd, Eb");
nextop = F8;
GETGD;
- if(MODREG) {
- if(rex.rex) {
- wback = xRAX+(nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ if (rex.rex) {
+ wback = xRAX + (nextop & 7) + (rex.b << 3);
wb2 = 0;
} else {
- wback = (nextop&7);
- wb2 = (wback>>2)*8;
- wback = xRAX+(wback&3);
+ wback = (nextop & 7);
+ wb2 = (wback >> 2) * 8;
+ wback = xRAX + (wback & 3);
}
- SLLI(gd, wback, 56-wb2);
+ SLLI(gd, wback, 56 - wb2);
SRAI(gd, gd, 56);
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x1, &fixedaddress, rex, NULL, 1, 0);
LB(gd, ed, fixedaddress);
}
- if(!rex.w)
+ if (!rex.w)
ZEROUP(gd);
break;
case 0xBF:
INST_NAME("MOVSX Gd, Ew");
nextop = F8;
GETGD;
- if(MODREG) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
SLLI(gd, ed, 48);
SRAI(gd, gd, 48);
} else {
@@ -1532,7 +1610,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x1, &fixedaddress, rex, NULL, 1, 0);
LH(gd, ed, fixedaddress);
}
- if(!rex.w)
+ if (!rex.w)
ZEROUP(gd);
break;
case 0xC2:
@@ -1543,12 +1621,12 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
u8 = F8;
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
- FLW(d0, gback, gdoffset+i*4);
- FLW(d1, wback, fixedaddress+i*4);
- if ((u8&7) == 0) { // Equal
+ for (int i = 0; i < 4; ++i) {
+ FLW(d0, gback, gdoffset + i * 4);
+ FLW(d1, wback, fixedaddress + i * 4);
+ if ((u8 & 7) == 0) { // Equal
FEQS(x3, d0, d1);
- } else if ((u8&7) == 4) { // Not Equal or unordered
+ } else if ((u8 & 7) == 4) { // Not Equal or unordered
FEQS(x3, d0, d1);
XORI(x3, x3, 1);
} else {
@@ -1557,41 +1635,47 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FEQS(x3, d1, d1);
AND(x3, x3, x4);
- switch(u8&7) {
- case 1: BEQ_MARK(x3, xZR); FLTS(x3, d0, d1); break; // Less than
- case 2: BEQ_MARK(x3, xZR); FLES(x3, d0, d1); break; // Less or equal
- case 3: XORI(x3, x3, 1); break; // NaN
- case 5: { // Greater or equal or unordered
- BEQ(x3, xZR, 12); // MARK2
- FLES(x3, d1, d0);
- J(8); // MARK;
- break;
- }
- case 6: { // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
- BEQ(x3, xZR, 12); // MARK2
- FLTS(x3, d1, d0);
- J(8); // MARK;
- break;
- }
- case 7: break; // Not NaN
+ switch (u8 & 7) {
+ case 1:
+ BEQ_MARK(x3, xZR);
+ FLTS(x3, d0, d1);
+ break; // Less than
+ case 2:
+ BEQ_MARK(x3, xZR);
+ FLES(x3, d0, d1);
+ break; // Less or equal
+ case 3: XORI(x3, x3, 1); break; // NaN
+ case 5: { // Greater or equal or unordered
+ BEQ(x3, xZR, 12); // MARK2
+ FLES(x3, d1, d0);
+ J(8); // MARK;
+ break;
+ }
+ case 6: { // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
+ BEQ(x3, xZR, 12); // MARK2
+ FLTS(x3, d1, d0);
+ J(8); // MARK;
+ break;
+ }
+ case 7: break; // Not NaN
}
// MARK2;
- if ((u8&7) == 5 || (u8&7) == 6) {
+ if ((u8 & 7) == 5 || (u8 & 7) == 6) {
MOV32w(x3, 1);
}
// MARK;
}
NEG(x3, x3);
- SW(x3, gback, gdoffset+i*4);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0xC3:
INST_NAME("MOVNTI Ed, Gd");
nextop = F8;
GETGD;
- if(MODREG) {
- MVxw(xRAX+(nextop&7)+(rex.b<<3), gd);
+ if (MODREG) {
+ MVxw(xRAX + (nextop & 7) + (rex.b << 3), gd);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
SDxw(gd, ed, fixedaddress);
@@ -1605,19 +1689,19 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
u8 = F8;
int32_t idx;
- idx = (u8>>(0*2))&3;
- LWU(x3, gback, gdoffset+idx*4);
- idx = (u8>>(1*2))&3;
- LWU(x4, gback, gdoffset+idx*4);
- idx = (u8>>(2*2))&3;
- LWU(x5, wback, fixedaddress+idx*4);
- idx = (u8>>(3*2))&3;
- LWU(x6, wback, fixedaddress+idx*4);
+ idx = (u8 >> (0 * 2)) & 3;
+ LWU(x3, gback, gdoffset + idx * 4);
+ idx = (u8 >> (1 * 2)) & 3;
+ LWU(x4, gback, gdoffset + idx * 4);
+ idx = (u8 >> (2 * 2)) & 3;
+ LWU(x5, wback, fixedaddress + idx * 4);
+ idx = (u8 >> (3 * 2)) & 3;
+ LWU(x6, wback, fixedaddress + idx * 4);
- SW(x3, gback, gdoffset+0*4);
- SW(x4, gback, gdoffset+1*4);
- SW(x5, gback, gdoffset+2*4);
- SW(x6, gback, gdoffset+3*4);
+ SW(x3, gback, gdoffset + 0 * 4);
+ SW(x4, gback, gdoffset + 1 * 4);
+ SW(x5, gback, gdoffset + 2 * 4);
+ SW(x6, gback, gdoffset + 3 * 4);
break;
case 0xC8:
@@ -1627,98 +1711,159 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xCC:
case 0xCD:
case 0xCE:
- case 0xCF: /* BSWAP reg */
+ case 0xCF: /* BSWAP reg */
INST_NAME("BSWAP Reg");
- gd = xRAX+(opcode&7)+(rex.b<<3);
- if(rv64_zbb) {
- REV8(gd, gd);
- if(!rex.w)
- SRLI(gd, gd, 32);
- } else {
- gback = gd;
- if (!rex.w) {
- AND(x4, gd, xMASK);
- gd = x4;
- }
- ANDI(x1, gd, 0xff);
- SLLI(x1, x1, (rex.w?64:32)-8);
- SRLI(x2, gd, 8);
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, (rex.w?64:32)-16);
- OR(x1, x1, x3);
- SRLI(x2, gd, 16);
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, (rex.w?64:32)-24);
- OR(x1, x1, x3);
- SRLI(x2, gd, 24);
- if(rex.w) {
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, 64-32);
- OR(x1, x1, x3);
- SRLI(x2, gd, 32);
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, 64-40);
- OR(x1, x1, x3);
- SRLI(x2, gd, 40);
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, 64-48);
- OR(x1, x1, x3);
- SRLI(x2, gd, 48);
- ANDI(x3, x2, 0xff);
- SLLI(x3, x3, 64-56);
- OR(x1, x1, x3);
- SRLI(x2, gd, 56);
- }
- OR(gback, x1, x2);
- }
+ gd = xRAX + (opcode & 7) + (rex.b << 3);
+ REV8xw(gd, gd, x1, x2, x3, x4);
+ break;
+ case 0xD5:
+ INST_NAME("PMULLW Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ MMX_LOOP_WS(x3, x4, MULW(x3, x3, x4));
+ break;
+ case 0xD9:
+ INST_NAME("PSUBUSW Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ MMX_LOOP_W(x3, x4, SUB(x3, x3, x4); SLT(x4, xZR, x3); NEG(x4, x4); AND(x3, x3, x4));
+ break;
+ case 0xDB:
+ INST_NAME("PAND Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x4, 0);
+ LD(x1, wback, fixedaddress);
+ LD(x2, gback, gdoffset);
+ AND(x1, x1, x2);
+ SD(x1, gback, gdoffset);
break;
case 0xE5:
INST_NAME("PMULHW Gm,Em");
nextop = F8;
GETGM();
GETEM(x2, 0);
- for(int i=0; i<4; ++i) {
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 4; ++i) {
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
MULW(x3, x3, x4);
SRAIW(x3, x3, 16);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
+ INST_NAME("PSUBSW Gm,Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ for (int i = 0; i < 4; ++i) {
+ LH(x3, gback, gdoffset + i * 2);
+ LH(x4, wback, fixedaddress);
+ SUBW(x3, x3, x4);
+ LUI(x4, 0xFFFF8); // -32768
+ BGE(x3, x4, 12);
+ SH(x4, gback, gdoffset + i * 2);
+ J(20); // continue
+ LUI(x4, 8); // 32768
+ BLT(x3, x4, 8);
+ ADDIW(x3, x4, -1);
+ SH(x4, gback, gdoffset + i * 2);
+ }
+ break;
+ case 0xE7:
+ INST_NAME("MOVNTQ Em, Gm");
+ nextop = F8;
+ gd = (nextop & 0x38) >> 3;
+ if (MODREG) {
+ DEFAULT;
+ } else {
+ v0 = mmx_get_reg(dyn, ninst, x1, x2, x3, gd);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FSD(v0, ed, fixedaddress);
+ }
+ break;
+ case 0xE9:
+ INST_NAME("PSUBSW Gm,Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ for (int i = 0; i < 4; ++i) {
+ // tmp32s = (int32_t)GM->sw[i] - EM->sw[i];
+ // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
+ SUBW(x3, x3, x4);
+ LUI(x4, 0xFFFF8); // -32768
+ BGE(x3, x4, 12);
+ SH(x4, gback, gdoffset + 2 * i);
+ J(20); // continue
+ LUI(x4, 8); // 32768
+ BLT(x3, x4, 8);
+ ADDIW(x3, x4, -1);
+ SH(x3, gback, gdoffset + 2 * i);
+ }
+ break;
+ case 0xEB:
+ INST_NAME("POR Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ LD(x3, gback, gdoffset);
+ LD(x4, wback, fixedaddress);
+ OR(x3, x3, x4);
+ SD(x3, gback, gdoffset);
+ break;
case 0xED:
INST_NAME("PADDSW Gm,Em");
nextop = F8;
GETGM();
GETEM(x2, 0);
- for(int i=0; i<4; ++i) {
- // tmp32s = (int32_t)GX->sw[i] + EX->sw[i];
- // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 4; ++i) {
+ // tmp32s = (int32_t)GM->sw[i] + EM->sw[i];
+ // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
ADDW(x3, x3, x4);
LUI(x4, 0xFFFF8); // -32768
BGE(x3, x4, 12);
- SH(x4, gback, gdoffset+2*i);
- J(20); // continue
+ SH(x4, gback, gdoffset + 2 * i);
+ J(20); // continue
LUI(x4, 8); // 32768
BLT(x3, x4, 8);
ADDIW(x3, x4, -1);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xEF:
INST_NAME("PXOR Gm,Em");
nextop = F8;
GETGM();
- if(MODREG && gd==(nextop&7)) {
+ if (MODREG && gd == (nextop & 7)) {
// just zero dest
- SD(xZR, gback, gdoffset+0);
+ SD(xZR, gback, gdoffset + 0);
} else {
GETEM(x2, 0);
- LD(x3, gback, gdoffset+0);
+ LD(x3, gback, gdoffset + 0);
LD(x4, wback, fixedaddress);
XOR(x3, x3, x4);
- SD(x3, gback, gdoffset+0);
+ SD(x3, gback, gdoffset + 0);
+ }
+ break;
+ case 0xF5:
+ INST_NAME("PMADDWD Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x5, 0);
+ for (int i = 0; i < 2; ++i) {
+ LH(x1, gback, gdoffset + i * 4);
+ LH(x2, gback, gdoffset + i * 4 + 2);
+ LH(x3, wback, fixedaddress + i * 4);
+ LH(x4, wback, fixedaddress + i * 4 + 2);
+ MULW(x1, x1, x3);
+ MULW(x2, x2, x4);
+ ADDW(x1, x1, x2);
+ SW(x1, gback, gdoffset + i * 4);
}
break;
case 0xF9:
@@ -1735,6 +1880,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETEM(x2, 0);
MMX_LOOP_W(x3, x4, ADDW(x3, x3, x4));
break;
+ case 0xFE:
+ INST_NAME("PADDD Gm, Em");
+ nextop = F8;
+ GETGM();
+ GETEM(x2, 0);
+ MMX_LOOP_D(x3, x4, ADDW(x3, x3, x4));
+ break;
default:
DEFAULT;
}
diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c
index bc3b2c9..ad022f5 100644
--- a/src/dynarec/rv64/dynarec_rv64_64.c
+++ b/src/dynarec/rv64/dynarec_rv64_64.c
@@ -393,7 +393,44 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
LDxw(gd, x4, fixedaddress);
}
break;
-
+ case 0x8E:
+ INST_NAME("MOV Seg,Ew");
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ u8 = (nextop&0x38) >> 3;
+ if ((nextop&0xC0) == 0xC0) {
+ ed = xRAX+(nextop&7) + (rex.b<<3);
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 0, 0);
+ ADD(x4, wback, x4);
+ LHU(x1, x4, 0);
+ ed = x1;
+ }
+ SH(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+ SW(xZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
+ break;
+ case 0x8F:
+ INST_NAME("POP FS:Ed");
+ grab_segdata(dyn, addr, ninst, x4, seg);
+ nextop = F8;
+ if (MODREG) {
+ POP1z(xRAX + (nextop & 7) + (rex.b << 3));
+ } else {
+ POP1z(x3); // so this can handle POP [ESP] and maybe some variant too
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 0, 0);
+ if (ed == xRSP) {
+ ADD(x4, ed, x4);
+ SDz(x3, x4, 0);
+ } else {
+ // complicated to just allow a segfault that can be recovered correctly
+ ADDIz(xRSP, xRSP, rex.is32bits ? -4 : -8);
+ ADD(x4, ed, x4);
+ SDz(x3, x4, 0);
+ ADDIz(xRSP, xRSP, rex.is32bits ? 4 : 8);
+ }
+ }
+ break;
case 0xA1:
INST_NAME("MOV EAX,FS:Od");
grab_segdata(dyn, addr, ninst, x4, seg);
@@ -489,6 +526,20 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SMWRITE2();
}
break;
+
+ case 0xFF:
+ nextop = F8;
+ grab_segdata(dyn, addr, ninst, x6, seg);
+ switch((nextop>>3)&7) {
+ case 6: // Push Ed
+ INST_NAME("PUSH Ed");
+ GETEDOz(x6, 0, x3);
+ PUSH1z(ed);
+ break;
+ default:
+ DEFAULT;
+ }
+ break;
default:
DEFAULT;
}
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 3e11d45..fdc2d7e 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -15,6 +15,7 @@
#include "emu/x64run_private.h"
#include "x64trace.h"
#include "dynarec_native.h"
+#include "custommem.h"
#include "rv64_printer.h"
#include "dynarec_rv64_private.h"
@@ -115,7 +116,11 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
OR(xRAX, xRAX, x1);
break;
case 0x0F:
- addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+ switch(rep) {
+ case 0: addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ case 1: addr = dynarec64_66F20F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ case 2: addr = dynarec64_66F30F(dyn, addr, ip, ninst, rex, ok, need_epilog); break;
+ }
break;
case 0x11:
INST_NAME("ADC Ew, Gw");
@@ -539,7 +544,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
OR(ed, ed, x2);
}
} else {
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 0, 0);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
SH(gd, ed, fixedaddress);
SMWRITELOCK(lock);
}
@@ -602,6 +607,29 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
AND(x1, x1, x2);
OR(xRAX, xRAX, x1);
break;
+ case 0xA1:
+ INST_NAME("MOV EAX,Od");
+ if (rex.is32bits) u64 = F32; else u64 = F64;
+ MOV64z(x1, u64);
+ if (isLockAddress(u64)) lock = 1; else lock = 0;
+ SMREADLOCK(lock);
+ LHU(x2, x1, 0);
+ LUI(x3, 0xffff0);
+ AND(xRAX, xRAX, x3);
+ OR(xRAX, xRAX, x2);
+ break;
+ case 0xA3:
+ INST_NAME("MOV Od,EAX");
+ if(rex.is32bits)
+ u64 = F32;
+ else
+ u64 = F64;
+ MOV64z(x1, u64);
+ if(isLockAddress(u64)) lock=1; else lock = 0;
+ SH(xRAX, x1, 0);
+ SMWRITELOCK(lock);
+ break;
+
case 0xA5:
if(rep) {
INST_NAME("REP MOVSW");
@@ -633,6 +661,48 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ADD(xRDI, xRDI, x3);
}
break;
+ case 0xA7:
+ switch (rep) {
+ case 1:
+ case 2:
+ if (rep == 1) { INST_NAME("REPNZ CMPSW"); } else { INST_NAME("REPZ CMPSW"); }
+ MAYSETFLAGS();
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ CBZ_NEXT(xRCX);
+ ANDI(x1, xFlags, 1 << F_DF);
+ BNEZ_MARK2(x1);
+ MARK; // Part with DF==0
+ LHU(x1, xRSI, 0);
+ ADDI(xRSI, xRSI, 2);
+ LHU(x2, xRDI, 0);
+ ADDI(xRDI, xRDI, 2);
+ SUBI(xRCX, xRCX, 1);
+ if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+ BNEZ_MARK(xRCX);
+ B_MARK3_nocond;
+ MARK2; // Part with DF==1
+ LHU(x1, xRSI, 0);
+ SUBI(xRSI, xRSI, 2);
+ LHU(x2, xRDI, 0);
+ SUBI(xRDI, xRDI, 2);
+ SUBI(xRCX, xRCX, 1);
+ if (rep == 1) { BEQ_MARK3(x1, x2); } else { BNE_MARK3(x1, x2); }
+ BNEZ_MARK2(xRCX);
+ MARK3; // end
+ emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6);
+ break;
+ default:
+ INST_NAME("CMPSW");
+ SETFLAGS(X_ALL, SF_SET_PENDING);
+ GETDIR(x3, x1, 2);
+ LHU(x1, xRSI, 0);
+ LHU(x2, xRDI, 0);
+ ADD(xRSI, xRSI, x3);
+ ADD(xRDI, xRDI, x3);
+ emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6);
+ break;
+ }
+ break;
case 0xA9:
INST_NAME("TEST AX,Iw");
SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -667,7 +737,19 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ADD(xRDI, xRDI, x3);
}
break;
-
+ case 0xAD:
+ if (rep) {
+ DEFAULT;
+ } else {
+ INST_NAME("LODSW");
+ GETDIR(x1, x2, 2);
+ LHU(x2, xRSI, 0);
+ ADD(xRSI, xRSI, x1);
+ LUI(x1, 0xffff0);
+ AND(xRAX, xRAX, x1);
+ OR(xRAX, xRAX, x2);
+ }
+ break;
case 0xAF:
switch (rep) {
case 1:
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index c60d214..f7953c5 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -23,7 +23,8 @@
uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
- (void)ip; (void)need_epilog;
+ (void)ip;
+ (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8, s8;
@@ -49,7 +50,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
static const int8_t round_round[] = { RD_RNE, RD_RDN, RD_RUP, RD_RTZ };
- switch(opcode) {
+ switch (opcode) {
case 0x10:
INST_NAME("MOVUPD Gx,Ex");
nextop = F8;
@@ -63,13 +64,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_MV_Q2(x3);
- if(!MODREG) SMWRITE2();
+ if (!MODREG) SMWRITE2();
break;
case 0x12:
INST_NAME("MOVLPD Gx, Eq");
nextop = F8;
GETGX();
- if(MODREG) {
+ if (MODREG) {
// access register instead of memory is bad opcode!
DEFAULT;
return addr;
@@ -77,19 +78,19 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
LD(x3, wback, fixedaddress);
- SD(x3, gback, gdoffset+0);
+ SD(x3, gback, gdoffset + 0);
break;
case 0x13:
INST_NAME("MOVLPD Eq, Gx");
nextop = F8;
GETGX();
- if(MODREG) {
+ if (MODREG) {
// access register instead of memory is bad opcode!
DEFAULT;
return addr;
}
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
- LD(x3, gback, gdoffset+0);
+ LD(x3, gback, gdoffset + 0);
SD(x3, wback, fixedaddress);
SMWRITE2();
break;
@@ -99,8 +100,8 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
// GX->q[1] = EX->q[0];
- LD(x3, wback, fixedaddress+0);
- SD(x3, gback, gdoffset+8);
+ LD(x3, wback, fixedaddress + 0);
+ SD(x3, gback, gdoffset + 8);
break;
case 0x15:
INST_NAME("UNPCKHPD Gx, Ex");
@@ -108,17 +109,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
// GX->q[0] = GX->q[1];
- LD(x3, gback, gdoffset+8);
- SD(x3, gback, gdoffset+0);
+ LD(x3, gback, gdoffset + 8);
+ SD(x3, gback, gdoffset + 0);
// GX->q[1] = EX->q[1];
- LD(x3, wback, fixedaddress+8);
- SD(x3, gback, gdoffset+8);
+ LD(x3, wback, fixedaddress + 8);
+ SD(x3, gback, gdoffset + 8);
break;
case 0x16:
INST_NAME("MOVHPD Gx, Eq");
nextop = F8;
GETGX();
- if(MODREG) {
+ if (MODREG) {
// access register instead of memory is bad opcode!
DEFAULT;
return addr;
@@ -126,7 +127,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
LD(x3, wback, fixedaddress);
- SD(x3, gback, gdoffset+8);
+ SD(x3, gback, gdoffset + 8);
break;
case 0x1F:
INST_NAME("NOP (multibyte)");
@@ -146,7 +147,19 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_MV_Q2(x3);
- if(!MODREG) SMWRITE2();
+ if (!MODREG) SMWRITE2();
+ break;
+ case 0x2A:
+ INST_NAME("CVTPI2PD Gx,Em");
+ nextop = F8;
+ GETGX();
+ GETEM(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ for (int i = 0; i < 2; ++i) {
+ LW(x1, wback, fixedaddress + i * 4);
+ FCVTDW(d0, x1, RD_RTZ);
+ FSD(d0, gback, gdoffset + i * 8);
+ }
break;
case 0x2B:
INST_NAME("MOVNTPD Ex, Gx");
@@ -155,10 +168,60 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
SSE_LOOP_MV_Q2(x3);
break;
+ case 0x2C:
+ INST_NAME("CVTTPD2PI Gm,Ex");
+ nextop = F8;
+ GETGM();
+ GETEX(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ for (int i = 0; i < 2; ++i) {
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
+ }
+ FLD(d0, wback, fixedaddress + i * 8);
+ FCVTWD(x1, d0, RD_RTZ);
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
+ BEQ_MARKi(x5, xZR, i);
+ MOV32w(x1, 0x80000000);
+ MARKi(i);
+ }
+ SW(x1, gback, gdoffset + i * 4);
+ }
+ break;
+ case 0x2D:
+ INST_NAME("CVTPD2PI Gm,Ex");
+ nextop = F8;
+ GETGM();
+ GETEX(x2, 0);
+ d0 = fpu_get_scratch(dyn);
+ u8 = sse_setround(dyn, ninst, x4, x5);
+ for (int i = 0; i < 2; ++i) {
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
+ }
+ FLD(d0, wback, fixedaddress + i * 8);
+ FCVTWD(x1, d0, RD_DYN);
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
+ BEQ_MARKi(x5, xZR, i);
+ MOV32w(x1, 0x80000000);
+ MARKi(i);
+ }
+ SW(x1, gback, gdoffset + i * 4);
+ }
+ x87_restoreround(dyn, ninst, u8);
+ break;
case 0x2E:
// no special check...
case 0x2F:
- if(opcode==0x2F) {INST_NAME("COMISD Gx, Ex");} else {INST_NAME("UCOMISD Gx, Ex");}
+ if (opcode == 0x2F) {
+ INST_NAME("COMISD Gx, Ex");
+ } else {
+ INST_NAME("UCOMISD Gx, Ex");
+ }
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE();
nextop = F8;
@@ -166,33 +229,36 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEXSD(v0, 0);
CLEAR_FLAGS();
// if isnan(d0) || isnan(v0)
- IFX(X_ZF | X_PF | X_CF) {
+ IFX(X_ZF | X_PF | X_CF)
+ {
FEQD(x3, d0, d0);
FEQD(x2, v0, v0);
AND(x2, x2, x3);
BNE_MARK(x2, xZR);
- ORI(xFlags, xFlags, (1<<F_ZF) | (1<<F_PF) | (1<<F_CF));
+ ORI(xFlags, xFlags, (1 << F_ZF) | (1 << F_PF) | (1 << F_CF));
B_NEXT_nocond;
}
MARK;
// else if isless(d0, v0)
- IFX(X_CF) {
+ IFX(X_CF)
+ {
FLTD(x2, d0, v0);
BEQ_MARK2(x2, xZR);
- ORI(xFlags, xFlags, 1<<F_CF);
+ ORI(xFlags, xFlags, 1 << F_CF);
B_NEXT_nocond;
}
MARK2;
// else if d0 == v0
- IFX(X_ZF) {
+ IFX(X_ZF)
+ {
FEQD(x2, d0, v0);
CBZ_NEXT(x2);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
}
break;
- case 0x38: // SSSE3 opcodes
+ case 0x38: // SSSE3 opcodes
nextop = F8;
- switch(nextop) {
+ switch (nextop) {
case 0x00:
INST_NAME("PSHUFB Gx, Ex");
nextop = F8;
@@ -203,46 +269,46 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
ADDI(x5, xEmu, offsetof(x64emu_t, scratch));
// perserve gd
- LD(x3, gback, gdoffset+0);
- LD(x4, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 0);
+ LD(x4, gback, gdoffset + 8);
SD(x3, x5, 0);
SD(x4, x5, 8);
- for (int i=0; i<16; ++i) {
- LBU(x3, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, wback, fixedaddress + i);
ANDI(x4, x3, 128);
BEQZ(x4, 12);
- SB(xZR, gback, gdoffset+i);
+ SB(xZR, gback, gdoffset + i);
BEQZ(xZR, 20); // continue
ANDI(x4, x3, 15);
ADD(x4, x4, x5);
LBU(x4, x4, 0);
- SB(x4, gback, gdoffset+i);
+ SB(x4, gback, gdoffset + i);
}
break;
case 0x01:
INST_NAME("PHADDW Gx, Ex");
nextop = F8;
GETGX();
- for (int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->sw[i] = GX->sw[i*2+0]+GX->sw[i*2+1];
- LH(x3, gback, gdoffset+2*(i*2+0));
- LH(x4, gback, gdoffset+2*(i*2+1));
+ LH(x3, gback, gdoffset + 2 * (i * 2 + 0));
+ LH(x4, gback, gdoffset + 2 * (i * 2 + 1));
ADDW(x3, x3, x4);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// GX->q[1] = GX->q[0];
- LD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 8);
} else {
GETEX(x2, 0);
- for (int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->sw[4+i] = EX->sw[i*2+0] + EX->sw[i*2+1];
- LH(x3, wback, fixedaddress+2*(i*2+0));
- LH(x4, wback, fixedaddress+2*(i*2+1));
+ LH(x3, wback, fixedaddress + 2 * (i * 2 + 0));
+ LH(x4, wback, fixedaddress + 2 * (i * 2 + 1));
ADDW(x3, x3, x4);
- SH(x3, gback, gdoffset+2*(4+i));
+ SH(x3, gback, gdoffset + 2 * (4 + i));
}
}
break;
@@ -251,31 +317,31 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
// GX->sd[0] += GX->sd[1];
- LW(x3, gback, gdoffset+0*4);
- LW(x4, gback, gdoffset+1*4);
+ LW(x3, gback, gdoffset + 0 * 4);
+ LW(x4, gback, gdoffset + 1 * 4);
ADDW(x3, x3, x4);
- SW(x3, gback, gdoffset+0*4);
+ SW(x3, gback, gdoffset + 0 * 4);
// GX->sd[1] = GX->sd[2] + GX->sd[3];
- LW(x3, gback, gdoffset+2*4);
- LW(x4, gback, gdoffset+3*4);
+ LW(x3, gback, gdoffset + 2 * 4);
+ LW(x4, gback, gdoffset + 3 * 4);
ADDW(x3, x3, x4);
- SW(x3, gback, gdoffset+1*4);
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
+ SW(x3, gback, gdoffset + 1 * 4);
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// GX->q[1] = GX->q[0];
- LD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 8);
} else {
GETEX(x2, 0);
// GX->sd[2] = EX->sd[0] + EX->sd[1];
- LW(x3, wback, fixedaddress+0*4);
- LW(x4, wback, fixedaddress+1*4);
+ LW(x3, wback, fixedaddress + 0 * 4);
+ LW(x4, wback, fixedaddress + 1 * 4);
ADDW(x3, x3, x4);
- SW(x3, gback, gdoffset+2*4);
+ SW(x3, gback, gdoffset + 2 * 4);
// GX->sd[3] = EX->sd[2] + EX->sd[3];
- LW(x3, wback, fixedaddress+2*4);
- LW(x4, wback, fixedaddress+3*4);
+ LW(x3, wback, fixedaddress + 2 * 4);
+ LW(x4, wback, fixedaddress + 3 * 4);
ADDW(x3, x3, x4);
- SW(x3, gback, gdoffset+3*4);
+ SW(x3, gback, gdoffset + 3 * 4);
}
break;
@@ -286,24 +352,24 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
MOV64x(x5, 32767);
MOV64x(x6, -32768);
- for(int i=0; i<8; ++i) {
- LBU(x3, gback, gdoffset+i*2);
- LB(x4, wback, fixedaddress+i*2);
+ for (int i = 0; i < 8; ++i) {
+ LBU(x3, gback, gdoffset + i * 2);
+ LB(x4, wback, fixedaddress + i * 2);
MUL(x9, x3, x4);
- LBU(x3, gback, gdoffset+i*2+1);
- LB(x4, wback, fixedaddress+i*2+1);
+ LBU(x3, gback, gdoffset + i * 2 + 1);
+ LB(x4, wback, fixedaddress + i * 2 + 1);
MUL(x3, x3, x4);
ADD(x3, x3, x9);
- if(rv64_zbb) {
+ if (rv64_zbb) {
MIN(x3, x3, x5);
MAX(x3, x3, x6);
} else {
- BLT(x3, x5, 4+4);
+ BLT(x3, x5, 4 + 4);
MV(x3, x5);
- BLT(x6, x3, 4+4);
+ BLT(x6, x3, 4 + 4);
MV(x3, x6);
}
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
@@ -312,14 +378,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
- BGE(x4, xZR, 4+4);
+ for (int i = 0; i < 16; ++i) {
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
+ BGE(x4, xZR, 4 + 4);
NEG(x3, x3);
- BNE(x4, xZR, 4+4);
+ BNE(x4, xZR, 4 + 4);
MOV_U12(x3, 0);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0x09:
@@ -327,14 +393,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+i*2);
- LH(x4, wback, fixedaddress+i*2);
- BGE(x4, xZR, 4+4);
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + i * 2);
+ LH(x4, wback, fixedaddress + i * 2);
+ BGE(x4, xZR, 4 + 4);
NEG(x3, x3);
- BNE(x4, xZR, 4+4);
+ BNE(x4, xZR, 4 + 4);
MOV_U12(x3, 0);
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
case 0x0A:
@@ -342,14 +408,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LW(x3, gback, gdoffset+i*4);
- LW(x4, wback, fixedaddress+i*4);
- BGE(x4, xZR, 4+4);
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, gback, gdoffset + i * 4);
+ LW(x4, wback, fixedaddress + i * 4);
+ BGE(x4, xZR, 4 + 4);
NEG(x3, x3);
- BNE(x4, xZR, 4+4);
+ BNE(x4, xZR, 4 + 4);
ADDI(x3, xZR, 0);
- SW(x3, gback, gdoffset+i*4);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0x0B:
@@ -357,14 +423,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+i*2);
- LH(x4, wback, fixedaddress+i*2);
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + i * 2);
+ LH(x4, wback, fixedaddress + i * 2);
MUL(x3, x3, x4);
SRAI(x3, x3, 14);
ADDI(x3, x3, 1);
SRAI(x3, x3, 1);
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
case 0x10:
@@ -373,11 +439,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
sse_forget_reg(dyn, ninst, 0); // forget xmm[0]
- for (int i=0; i<16; ++i) {
- LB(x3, xEmu, offsetof(x64emu_t, xmm[0])+i);
+ for (int i = 0; i < 16; ++i) {
+ LB(x3, xEmu, offsetof(x64emu_t, xmm[0]) + i);
BGE(x3, xZR, 12); // continue
- LBU(x3, wback, fixedaddress+i);
- SB(x3, gback, gdoffset+i);
+ LBU(x3, wback, fixedaddress + i);
+ SB(x3, gback, gdoffset + i);
// continue
}
break;
@@ -389,29 +455,32 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
CLEAR_FLAGS();
SET_DFNONE();
- IFX(X_ZF|X_CF) {
- LD(x5, wback, fixedaddress+0);
- LD(x6, wback, fixedaddress+8);
+ IFX(X_ZF | X_CF)
+ {
+ LD(x5, wback, fixedaddress + 0);
+ LD(x6, wback, fixedaddress + 8);
- IFX(X_ZF) {
- LD(x3, gback, gdoffset+0);
- LD(x4, gback, gdoffset+8);
+ IFX(X_ZF)
+ {
+ LD(x3, gback, gdoffset + 0);
+ LD(x4, gback, gdoffset + 8);
AND(x3, x3, x5);
AND(x4, x4, x6);
OR(x3, x3, x4);
BNEZ(x3, 8);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
}
- IFX(X_CF) {
- LD(x3, gback, gdoffset+0);
+ IFX(X_CF)
+ {
+ LD(x3, gback, gdoffset + 0);
NOT(x3, x3);
- LD(x4, gback, gdoffset+8);
+ LD(x4, gback, gdoffset + 8);
NOT(x4, x4);
AND(x3, x3, x5);
AND(x4, x4, x6);
OR(x3, x3, x4);
BNEZ(x3, 8);
- ORI(xFlags, xFlags, 1<<F_CF);
+ ORI(xFlags, xFlags, 1 << F_CF);
}
}
break;
@@ -421,11 +490,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
- LB(x4, wback, fixedaddress+i);
- BGE(x4, xZR, 4+4);
+ for (int i = 0; i < 16; ++i) {
+ LB(x4, wback, fixedaddress + i);
+ BGE(x4, xZR, 4 + 4);
NEG(x4, x4);
- SB(x4, gback, gdoffset+i);
+ SB(x4, gback, gdoffset + i);
}
break;
case 0x1D:
@@ -433,11 +502,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LH(x4, wback, fixedaddress+i*2);
- BGE(x4, xZR, 4+4);
+ for (int i = 0; i < 8; ++i) {
+ LH(x4, wback, fixedaddress + i * 2);
+ BGE(x4, xZR, 4 + 4);
NEG(x4, x4);
- SH(x4, gback, gdoffset+i*2);
+ SH(x4, gback, gdoffset + i * 2);
}
break;
case 0x1E:
@@ -445,12 +514,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- MOV64x(x5, ~(1<<31));
- for(int i=0; i<4; ++i) {
- LW(x4, wback, fixedaddress+i*4);
- BGE(x4, xZR, 4+4);
+ MOV64x(x5, ~(1 << 31));
+ for (int i = 0; i < 4; ++i) {
+ LW(x4, wback, fixedaddress + i * 4);
+ BGE(x4, xZR, 4 + 4);
NEG(x4, x4);
- SW(x4, gback, gdoffset+i*4);
+ SW(x4, gback, gdoffset + i * 4);
}
break;
@@ -460,35 +529,36 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
MOV64x(x5, 65535);
- for(int i=0; i<4; ++i) {
- LW(x3, gback, gdoffset+i*4);
- if(rv64_zbb) {
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, gback, gdoffset + i * 4);
+ if (rv64_zbb) {
MIN(x3, x3, x5);
MAX(x3, x3, xZR);
} else {
- BGE(x3, xZR, 4+4);
+ BGE(x3, xZR, 4 + 4);
MV(x3, xZR);
- BLT(x3, x5, 4+4);
+ BLT(x3, x5, 4 + 4);
MV(x3, x5);
}
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
- if(MODREG && gd==ed) {
- LD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+8);
- } else for(int i=0; i<4; ++i) {
- LW(x3, wback, fixedaddress+i*4);
- if(rv64_zbb) {
- MIN(x3, x3, x5);
- MAX(x3, x3, xZR);
- } else {
- BGE(x3, xZR, 4+4);
- MV(x3, xZR);
- BLT(x3, x5, 4+4);
- MV(x3, x5);
+ if (MODREG && gd == ed) {
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 8);
+ } else
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, wback, fixedaddress + i * 4);
+ if (rv64_zbb) {
+ MIN(x3, x3, x5);
+ MAX(x3, x3, xZR);
+ } else {
+ BGE(x3, xZR, 4 + 4);
+ MV(x3, xZR);
+ BLT(x3, x5, 4 + 4);
+ MV(x3, x5);
+ }
+ SH(x3, gback, gdoffset + 8 + i * 2);
}
- SH(x3, gback, gdoffset+8+i*2);
- }
break;
case 0x30:
@@ -496,9 +566,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=7; i>=0; --i) {
- LBU(x3, wback, fixedaddress+i);
- SH(x3, gback, gdoffset+i*2);
+ for (int i = 7; i >= 0; --i) {
+ LBU(x3, wback, fixedaddress + i);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
case 0x31:
@@ -506,9 +576,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=3; i>=0; --i) {
- LBU(x3, wback, fixedaddress+i);
- SW(x3, gback, gdoffset+i*4);
+ for (int i = 3; i >= 0; --i) {
+ LBU(x3, wback, fixedaddress + i);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0x32:
@@ -516,9 +586,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=1; i>=0; --i) {
- LBU(x3, wback, fixedaddress+i);
- SD(x3, gback, gdoffset+i*8);
+ for (int i = 1; i >= 0; --i) {
+ LBU(x3, wback, fixedaddress + i);
+ SD(x3, gback, gdoffset + i * 8);
}
break;
case 0x33:
@@ -526,9 +596,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=3; i>=0; --i) {
- LHU(x3, wback, fixedaddress+i*2);
- SW(x3, gback, gdoffset+i*4);
+ for (int i = 3; i >= 0; --i) {
+ LHU(x3, wback, fixedaddress + i * 2);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0x34:
@@ -536,9 +606,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=1; i>=0; --i) {
- LHU(x3, wback, fixedaddress+i*2);
- SD(x3, gback, gdoffset+i*8);
+ for (int i = 1; i >= 0; --i) {
+ LHU(x3, wback, fixedaddress + i * 2);
+ SD(x3, gback, gdoffset + i * 8);
}
break;
case 0x35:
@@ -546,106 +616,130 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=1; i>=0; --i) {
- LWU(x3, wback, fixedaddress+i*4);
- SD(x3, gback, gdoffset+i*8);
+ for (int i = 1; i >= 0; --i) {
+ LWU(x3, wback, fixedaddress + i * 4);
+ SD(x3, gback, gdoffset + i * 8);
}
break;
case 0x38:
- INST_NAME("PMINSB Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMINSB Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
- if(rv64_zbb) MIN(x4, x3, x4); else BLT(x3, x4, 4+4);
- SB(x4, gback, gdoffset+i);
+ for (int i = 0; i < 16; ++i) {
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
+ if (rv64_zbb)
+ MIN(x4, x3, x4);
+ else
+ BLT(x3, x4, 4 + 4);
+ SB(x4, gback, gdoffset + i);
}
break;
case 0x39:
- INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LW(x3, gback, gdoffset+i*4);
- LW(x4, wback, fixedaddress+i*4);
- if(rv64_zbb) MIN(x4, x3, x4); else BLT(x3, x4, 4+4);
- SW(x4, gback, gdoffset+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, gback, gdoffset + i * 4);
+ LW(x4, wback, fixedaddress + i * 4);
+ if (rv64_zbb)
+ MIN(x4, x3, x4);
+ else
+ BLT(x3, x4, 4 + 4);
+ SW(x4, gback, gdoffset + i * 4);
}
break;
case 0x3A:
- INST_NAME("PMINUW Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMINUW Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LHU(x3, gback, gdoffset+i*2);
- LHU(x4, wback, fixedaddress+i*2);
- if(rv64_zbb) MINU(x4, x3, x4); else BLTU(x3, x4, 4+4);
- SH(x4, gback, gdoffset+i*2);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x3, gback, gdoffset + i * 2);
+ LHU(x4, wback, fixedaddress + i * 2);
+ if (rv64_zbb)
+ MINU(x4, x3, x4);
+ else
+ BLTU(x3, x4, 4 + 4);
+ SH(x4, gback, gdoffset + i * 2);
}
break;
case 0x3B:
- INST_NAME("PMINUD Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMINUD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LWU(x3, gback, gdoffset+i*4);
- LWU(x4, wback, fixedaddress+i*4);
- if(rv64_zbb) MINU(x4, x3, x4); else BLTU(x3, x4, 4+4);
- SW(x4, gback, gdoffset+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LWU(x3, gback, gdoffset + i * 4);
+ LWU(x4, wback, fixedaddress + i * 4);
+ if (rv64_zbb)
+ MINU(x4, x3, x4);
+ else
+ BLTU(x3, x4, 4 + 4);
+ SW(x4, gback, gdoffset + i * 4);
}
break;
case 0x3C:
- INST_NAME("PMAXSB Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMAXSB Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
- if(rv64_zbb) MAX(x4, x3, x4); else BLT(x4, x3, 4+4);
- SB(x4, gback, gdoffset+i);
+ for (int i = 0; i < 16; ++i) {
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
+ if (rv64_zbb)
+ MAX(x4, x3, x4);
+ else
+ BLT(x4, x3, 4 + 4);
+ SB(x4, gback, gdoffset + i);
}
break;
case 0x3D:
- INST_NAME("PMAXSD Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMAXSD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LW(x3, gback, gdoffset+i*4);
- LW(x4, wback, fixedaddress+i*4);
- if(rv64_zbb) MAX(x4, x3, x4); else BLT(x4, x3, 4+4);
- SW(x4, gback, gdoffset+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, gback, gdoffset + i * 4);
+ LW(x4, wback, fixedaddress + i * 4);
+ if (rv64_zbb)
+ MAX(x4, x3, x4);
+ else
+ BLT(x4, x3, 4 + 4);
+ SW(x4, gback, gdoffset + i * 4);
}
break;
case 0x3E:
- INST_NAME("PMAXUW Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMAXUW Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LHU(x3, gback, gdoffset+i*2);
- LHU(x4, wback, fixedaddress+i*2);
- if(rv64_zbb) MAXU(x4, x3, x4); else BLTU(x4, x3, 4+4);
- SH(x4, gback, gdoffset+i*2);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x3, gback, gdoffset + i * 2);
+ LHU(x4, wback, fixedaddress + i * 2);
+ if (rv64_zbb)
+ MAXU(x4, x3, x4);
+ else
+ BLTU(x4, x3, 4 + 4);
+ SH(x4, gback, gdoffset + i * 2);
}
break;
case 0x3F:
- INST_NAME("PMAXUD Gx, Ex"); // SSE4 opcode!
+ INST_NAME("PMAXUD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LWU(x3, gback, gdoffset+i*4);
- LWU(x4, wback, fixedaddress+i*4);
- if(rv64_zbb) MAXU(x4, x3, x4); else BLTU(x4, x3, 4+4);
- SW(x4, gback, gdoffset+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LWU(x3, gback, gdoffset + i * 4);
+ LWU(x4, wback, fixedaddress + i * 4);
+ if (rv64_zbb)
+ MAXU(x4, x3, x4);
+ else
+ BLTU(x4, x3, 4 + 4);
+ SW(x4, gback, gdoffset + i * 4);
}
break;
case 0x40:
@@ -653,15 +747,15 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<4; ++i) {
- LW(x3, gback, gdoffset+i*4);
- LW(x4, wback, fixedaddress+i*4);
+ for (int i = 0; i < 4; ++i) {
+ LW(x3, gback, gdoffset + i * 4);
+ LW(x4, wback, fixedaddress + i * 4);
MUL(x3, x3, x4);
- SW(x3, gback, gdoffset+i*4);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0xDB:
- INST_NAME("AESIMC Gx, Ex"); // AES-NI
+ INST_NAME("AESIMC Gx, Ex"); // AES-NI
nextop = F8;
GETGX();
GETEX(x2, 0);
@@ -671,7 +765,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
CALL(native_aesimc, -1);
break;
case 0xDC:
- INST_NAME("AESENC Gx, Ex"); // AES-NI
+ INST_NAME("AESENC Gx, Ex"); // AES-NI
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
@@ -682,7 +776,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
break;
case 0xDD:
- INST_NAME("AESENCLAST Gx, Ex"); // AES-NI
+ INST_NAME("AESENCLAST Gx, Ex"); // AES-NI
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
@@ -693,7 +787,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
break;
case 0xDE:
- INST_NAME("AESDEC Gx, Ex"); // AES-NI
+ INST_NAME("AESDEC Gx, Ex"); // AES-NI
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
@@ -705,7 +799,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0xDF:
- INST_NAME("AESDECLAST Gx, Ex"); // AES-NI
+ INST_NAME("AESDECLAST Gx, Ex"); // AES-NI
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
@@ -717,14 +811,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0xF0:
INST_NAME("MOVBE Gw, Ew");
- nextop=F8;
+ nextop = F8;
GETGD;
SMREAD();
- addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0);
LHU(x1, ed, fixedaddress);
if (rv64_zbb) {
REV8(x1, x1);
SRLI(x1, x1, 48);
+ } else if (rv64_xtheadbb) {
+ TH_REVW(x1, x1);
+ SRLI(x1, x1, 16);
} else {
ANDI(x2, x1, 0xff);
SLLI(x2, x2, 8);
@@ -733,17 +830,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
}
LUI(x2, 0xffff0);
AND(gd, gd, x2);
- OR(gd, gd, x1);
+ OR(gd, gd, x1);
break;
case 0xF1:
INST_NAME("MOVBE Ew, Gw");
- nextop=F8;
+ nextop = F8;
GETGD;
SMREAD();
- addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 0, 1);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, 0);
if (rv64_zbb) {
REV8(x1, gd);
SRLI(x1, x1, 48);
+ } else if (rv64_xtheadbb) {
+ TH_REVW(x1, gd);
+ SRLI(x1, x1, 16);
} else {
ANDI(x1, gd, 0xff);
SLLI(x1, x1, 8);
@@ -757,9 +857,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
DEFAULT;
}
break;
- case 0x3A: // these are some more SSSE3+ opcodes
+ case 0x3A: // these are some more SSSE3+ opcodes
opcode = F8;
- switch(opcode) {
+ switch (opcode) {
case 0x0B:
INST_NAME("ROUNDSD Gx, Ex, Ib");
nextop = F8;
@@ -770,7 +870,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
FEQD(x2, d0, d0);
BNEZ_MARK(x2);
- if (v0!=d0) FMVD(v0, d0);
+ if (v0 != d0) FMVD(v0, d0);
B_NEXT_nocond;
MARK; // d0 is not nan
FABSD(v1, d0);
@@ -778,16 +878,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
FCVTDL(d1, x3, RD_RTZ);
FLTD(x3, v1, d1);
BNEZ_MARK2(x3);
- if (v0!=d0) FMVD(v0, d0);
+ if (v0 != d0) FMVD(v0, d0);
B_NEXT_nocond;
MARK2;
- if(u8&4) {
+ if (u8 & 4) {
u8 = sse_setround(dyn, ninst, x4, x2);
FCVTLD(x5, d0, RD_DYN);
FCVTDL(v0, x5, RD_RTZ);
x87_restoreround(dyn, ninst, u8);
} else {
- FCVTLD(x5, d0, round_round[u8&3]);
+ FCVTLD(x5, d0, round_round[u8 & 3]);
FCVTDL(v0, x5, RD_RTZ);
}
break;
@@ -813,20 +913,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
FLTD(x4, v1, d1);
BNEZ(x4, 8);
B_MARK_nocond;
- if(u8&4) {
+ if (u8 & 4) {
u8 = sse_setround(dyn, ninst, x4, x5);
FCVTLD(x5, d0, RD_DYN);
FCVTDL(d0, x5, RD_RTZ);
x87_restoreround(dyn, ninst, u8);
} else {
- FCVTLD(x5, d0, round_round[u8&3]);
+ FCVTLD(x5, d0, round_round[u8 & 3]);
FCVTDL(d0, x5, RD_RTZ);
}
MARK;
- FSD(d0, gback, gdoffset+0);
+ FSD(d0, gback, gdoffset + 0);
// i = 1
- FLD(d0, wback, fixedaddress+8);
+ FLD(d0, wback, fixedaddress + 8);
FEQD(x4, d0, d0);
BNEZ(x4, 8);
B_MARK2_nocond;
@@ -835,17 +935,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
FLTD(x4, v1, d1);
BNEZ(x4, 8);
B_MARK2_nocond;
- if(u8&4) {
+ if (u8 & 4) {
u8 = sse_setround(dyn, ninst, x4, x5);
FCVTLD(x5, d0, RD_DYN);
FCVTDL(d0, x5, RD_RTZ);
x87_restoreround(dyn, ninst, u8);
} else {
- FCVTLD(x5, d0, round_round[u8&3]);
+ FCVTLD(x5, d0, round_round[u8 & 3]);
FCVTDL(d0, x5, RD_RTZ);
}
MARK2;
- FSD(d0, gback, gdoffset+8);
+ FSD(d0, gback, gdoffset + 8);
break;
case 0x0E:
INST_NAME("PBLENDW Gx, Ex, Ib");
@@ -854,34 +954,34 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 1);
u8 = F8;
i32 = 0;
- if (MODREG && gd==ed) break;
+ if (MODREG && gd == ed) break;
while (u8)
- if(u8&1) {
- if(!(i32&1) && u8&2) {
- if(!(i32&3) && (u8&0xf)==0xf) {
+ if (u8 & 1) {
+ if (!(i32 & 1) && u8 & 2) {
+ if (!(i32 & 3) && (u8 & 0xf) == 0xf) {
// whole 64bits
- LD(x3, wback, fixedaddress+8*(i32>>2));
- SD(x3, gback, gdoffset+8*(i32>>2));
- i32+=4;
- u8>>=4;
+ LD(x3, wback, fixedaddress + 8 * (i32 >> 2));
+ SD(x3, gback, gdoffset + 8 * (i32 >> 2));
+ i32 += 4;
+ u8 >>= 4;
} else {
// 32bits
- LWU(x3, wback, fixedaddress+4*(i32>>1));
- SW(x3, gback, gdoffset+4*(i32>>1));
- i32+=2;
- u8>>=2;
+ LWU(x3, wback, fixedaddress + 4 * (i32 >> 1));
+ SW(x3, gback, gdoffset + 4 * (i32 >> 1));
+ i32 += 2;
+ u8 >>= 2;
}
} else {
// 16 bits
- LHU(x3, wback, fixedaddress+2*i32);
- SH(x3, gback, gdoffset+2*i32);
+ LHU(x3, wback, fixedaddress + 2 * i32);
+ SH(x3, gback, gdoffset + 2 * i32);
i32++;
- u8>>=1;
+ u8 >>= 1;
}
} else {
// nope
i32++;
- u8>>=1;
+ u8 >>= 1;
}
break;
case 0x0F:
@@ -893,38 +993,42 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
sse_forget_reg(dyn, ninst, x5);
ADDI(x5, xEmu, offsetof(x64emu_t, scratch));
// perserve gd
- LD(x3, gback, gdoffset+0);
- LD(x4, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 0);
+ LD(x4, gback, gdoffset + 8);
SD(x3, x5, 0);
SD(x4, x5, 8);
- if(u8>31) {
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ if (u8 > 31) {
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
} else {
- for (int i=0; i<16; ++i, ++u8) {
- if (u8>15) {
- if(u8>31) {
- SB(xZR, gback, gdoffset+i);
+ for (int i = 0; i < 16; ++i, ++u8) {
+ if (u8 > 15) {
+ if (u8 > 31) {
+ SB(xZR, gback, gdoffset + i);
continue;
- }
- else LBU(x3, x5, u8-16);
+ } else
+ LBU(x3, x5, u8 - 16);
} else {
- LBU(x3, wback, fixedaddress+u8);
+ LBU(x3, wback, fixedaddress + u8);
}
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
}
break;
case 0x16:
- if(rex.w) {INST_NAME("PEXTRQ Ed, Gx, Ib");} else {INST_NAME("PEXTRD Ed, Gx, Ib");}
+ if (rex.w) {
+ INST_NAME("PEXTRQ Ed, Gx, Ib");
+ } else {
+ INST_NAME("PEXTRD Ed, Gx, Ib");
+ }
nextop = F8;
GETGX();
GETED(1);
u8 = F8;
- if(rex.w)
- LD(ed, gback, gdoffset+8*(u8&1));
+ if (rex.w)
+ LD(ed, gback, gdoffset + 8 * (u8 & 1));
else
- LWU(ed, gback, gdoffset+4*(u8&3));
+ LWU(ed, gback, gdoffset + 4 * (u8 & 3));
if (wback) {
SDxw(ed, wback, fixedaddress);
SMWRITE2();
@@ -936,7 +1040,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETED(1);
u8 = F8;
- SB(ed, gback, gdoffset+u8&0xF);
+ SB(ed, gback, gdoffset + u8 & 0xF);
break;
case 0x21:
INST_NAME("INSERTPS GX, EX, Ib");
@@ -944,14 +1048,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 1);
u8 = F8;
- if(MODREG) s8 = (u8>>6)&3; else s8 = 0;
+ if (MODREG)
+ s8 = (u8 >> 6) & 3;
+ else
+ s8 = 0;
// GX->ud[(tmp8u>>4)&3] = EX->ud[tmp8s];
- LWU(x3, wback, fixedaddress+4*s8);
- SW(x3, gback, gdoffset+4*(u8>>4));
- for(int i=0; i<4; ++i) {
- if(u8&(1<<i))
+ LWU(x3, wback, fixedaddress + 4 * s8);
+ SW(x3, gback, gdoffset + 4 * (u8 >> 4));
+ for (int i = 0; i < 4; ++i) {
+ if (u8 & (1 << i))
// GX->ud[i] = 0;
- SW(xZR, gback, gdoffset+4*i);
+ SW(xZR, gback, gdoffset + 4 * i);
}
break;
case 0x22:
@@ -960,10 +1067,10 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETED(1);
u8 = F8;
- if(rex.w) {
- SD(ed, gback, gdoffset+8*(u8&0x1));
+ if (rex.w) {
+ SD(ed, gback, gdoffset + 8 * (u8 & 0x1));
} else {
- SW(ed, gback, gdoffset+4*(u8&0x3));
+ SW(ed, gback, gdoffset + 4 * (u8 & 0x3));
}
break;
case 0x44:
@@ -972,15 +1079,15 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETG;
sse_forget_reg(dyn, ninst, gd);
MOV32w(x1, gd); // gx
- if(MODREG) {
- ed = (nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = (nextop & 7) + (rex.b << 3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x2, ed);
- MOV32w(x3, 0); // p = NULL
+ MOV32w(x3, 0); // p = NULL
} else {
MOV32w(x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x5, &fixedaddress, rex, NULL, 0, 1);
- if(ed!=x3) {
+ if (ed != x3) {
MV(x3, ed);
}
}
@@ -989,20 +1096,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
CALL(native_pclmul, -1);
break;
case 0xDF:
- INST_NAME("AESKEYGENASSIST Gx, Ex, Ib"); // AES-NI
+ INST_NAME("AESKEYGENASSIST Gx, Ex, Ib"); // AES-NI
nextop = F8;
GETG;
sse_forget_reg(dyn, ninst, gd);
MOV32w(x1, gd); // gx
- if(MODREG) {
- ed = (nextop&7)+(rex.b<<3);
+ if (MODREG) {
+ ed = (nextop & 7) + (rex.b << 3);
sse_forget_reg(dyn, ninst, ed);
MOV32w(x2, ed);
- MOV32w(x3, 0); //p = NULL
+ MOV32w(x3, 0); // p = NULL
} else {
MOV32w(x2, 0);
addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 0, 1);
- if(ed!=x3) {
+ if (ed != x3) {
MV(x3, ed);
}
}
@@ -1010,41 +1117,41 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
MOV32w(x4, u8);
CALL(native_aeskeygenassist, -1);
break;
- default:
+ default:
DEFAULT;
}
break;
- #define GO(GETFLAGS, NO, YES, F) \
- READFLAGS(F); \
- GETFLAGS; \
- nextop=F8; \
- GETGD; \
- if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- ZEXTH(x4, ed); \
- ed = x4; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \
- LHU(x4, ed, fixedaddress); \
- ed = x4; \
- } \
- B##NO(x1, 4+3*4); \
- LUI(x3, 0xffff0); \
- AND(gd, gd, x3); \
- OR(gd, gd, ed);
+#define GO(GETFLAGS, NO, YES, F) \
+ READFLAGS(F); \
+ GETFLAGS; \
+ nextop = F8; \
+ GETGD; \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ ZEXTH(x4, ed); \
+ ed = x4; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \
+ LHU(x4, ed, fixedaddress); \
+ ed = x4; \
+ } \
+ B##NO(x1, 4 + 3 * 4); \
+ LUI(x3, 0xffff0); \
+ AND(gd, gd, x3); \
+ OR(gd, gd, ed);
- GOCOND(0x40, "CMOV", "Gw, Ew");
- #undef GO
+ GOCOND(0x40, "CMOV", "Gw, Ew");
+#undef GO
case 0x50:
INST_NAME("PMOVMSKD Gd, Ex");
nextop = F8;
GETGD;
GETEX(x1, 0);
MV(gd, xZR);
- for(int i=0; i<2; ++i) {
+ for (int i = 0; i < 2; ++i) {
// GD->dword[0] |= ((EX->q[i]>>63)&1)<<i;
- LD(x2, wback, fixedaddress+8*i);
+ LD(x2, wback, fixedaddress + 8 * i);
SRLI(x2, x2, 63);
if (i) SLLI(x2, x2, 1);
OR(gd, gd, x2);
@@ -1056,21 +1163,21 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
d1 = fpu_get_scratch(dyn);
FMVDX(d1, xZR);
}
- for (int i=0; i<2; ++i) {
- FLD(d0, wback, fixedaddress+i*8);
- if(!box64_dynarec_fastnan) {
+ for (int i = 0; i < 2; ++i) {
+ FLD(d0, wback, fixedaddress + i * 8);
+ if (!box64_dynarec_fastnan) {
FLTD(x3, d0, d1);
}
FSQRTD(d0, d0);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
BEQ(x3, xZR, 8);
FNEGD(d0, d0);
}
- FSD(d0, gback, gdoffset+i*8);
+ FSD(d0, gback, gdoffset + i * 8);
}
break;
case 0x54:
@@ -1107,12 +1214,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_FQ(x3, x4, {
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x3, v0, v0);
FEQD(x4, v1, v1);
}
FADDD(v0, v0, v1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
AND(x3, x3, x4);
BEQZ(x3, 16);
FEQD(x3, v0, v0);
@@ -1127,12 +1234,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_FQ(x3, x4, {
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x3, v0, v0);
FEQD(x4, v1, v1);
}
FMULD(v0, v0, v1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
AND(x3, x3, x4);
BEQZ(x3, 16);
FEQD(x3, v0, v0);
@@ -1148,15 +1255,15 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
// GX->f[0] = EX->d[0];
- FLD(d0, wback, fixedaddress+0);
+ FLD(d0, wback, fixedaddress + 0);
FCVTSD(d0, d0);
- FSD(d0, gback, gdoffset+0);
+ FSD(d0, gback, gdoffset + 0);
// GX->f[1] = EX->d[1];
- FLD(d0, wback, fixedaddress+8);
+ FLD(d0, wback, fixedaddress + 8);
FCVTSD(d0, d0);
- FSD(d0, gback, gdoffset+4);
+ FSD(d0, gback, gdoffset + 4);
// GX->q[1] = 0;
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 8);
break;
case 0x5B:
INST_NAME("CVTPS2DQ Gx, Ex");
@@ -1165,14 +1272,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
u8 = sse_setround(dyn, ninst, x6, x4);
- for (int i=0; i<4; ++i) {
- FLW(d0, wback, fixedaddress+4*i);
+ for (int i = 0; i < 4; ++i) {
+ FLW(d0, wback, fixedaddress + 4 * i);
FCVTLS(x3, d0, RD_DYN);
SEXT_W(x5, x3);
SUB(x5, x5, x3);
BEQZ(x5, 8);
LUI(x3, 0x80000); // INT32_MIN
- SW(x3, gback, gdoffset+4*i);
+ SW(x3, gback, gdoffset + 4 * i);
}
x87_restoreround(dyn, ninst, u8);
break;
@@ -1182,12 +1289,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_FQ(x3, x4, {
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x3, v0, v0);
FEQD(x4, v1, v1);
}
FSUBD(v0, v0, v1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
AND(x3, x3, x4);
BEQZ(x3, 16);
FEQD(x3, v0, v0);
@@ -1203,16 +1310,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
- for (int i=0; i<2; ++i) {
- FLD(d0, gback, gdoffset+8*i);
- FLD(d1, wback, fixedaddress+8*i);
+ for (int i = 0; i < 2; ++i) {
+ FLD(d0, gback, gdoffset + 8 * i);
+ FLD(d1, wback, fixedaddress + 8 * i);
FEQD(x3, d0, d0);
FEQD(x4, d1, d1);
AND(x3, x3, x4);
BEQ(x3, xZR, 12);
FLTD(x3, d1, d0);
BEQ(x3, xZR, 8); // continue
- FSD(d1, gback, gdoffset+8*i);
+ FSD(d1, gback, gdoffset + 8 * i);
}
break;
case 0x5E:
@@ -1221,12 +1328,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
SSE_LOOP_FQ(x3, x4, {
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x3, v0, v0);
FEQD(x4, v1, v1);
}
FDIVD(v0, v0, v1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
AND(x3, x3, x4);
BEQZ(x3, 16);
FEQD(x3, v0, v0);
@@ -1242,39 +1349,39 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
- for (int i=0; i<2; ++i) {
- FLD(d0, gback, gdoffset+8*i);
- FLD(d1, wback, fixedaddress+8*i);
+ for (int i = 0; i < 2; ++i) {
+ FLD(d0, gback, gdoffset + 8 * i);
+ FLD(d1, wback, fixedaddress + 8 * i);
FEQD(x3, d0, d0);
FEQD(x4, d1, d1);
AND(x3, x3, x4);
BEQ(x3, xZR, 12);
FLTD(x3, d0, d1);
BEQ(x3, xZR, 8); // continue
- FSD(d1, gback, gdoffset+8*i);
+ FSD(d1, gback, gdoffset + 8 * i);
}
break;
case 0x60:
INST_NAME("PUNPCKLBW Gx,Ex");
nextop = F8;
GETGX();
- for(int i=7; i>0; --i) { // 0 is untouched
+ for (int i = 7; i > 0; --i) { // 0 is untouched
// GX->ub[2 * i] = GX->ub[i];
- LBU(x3, gback, gdoffset+i);
- SB(x3, gback, gdoffset+2*i);
+ LBU(x3, gback, gdoffset + i);
+ SB(x3, gback, gdoffset + 2 * i);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
- for(int i=0; i<8; ++i) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[2 * i + 1] = GX->ub[2 * i];
- LBU(x3, gback, gdoffset+2*i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, gback, gdoffset + 2 * i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
} else {
GETEX(x1, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[2 * i + 1] = EX->ub[i];
- LBU(x3, wback, fixedaddress+i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, wback, fixedaddress + i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
}
break;
@@ -1282,23 +1389,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PUNPCKLWD Gx,Ex");
nextop = F8;
GETGX();
- for(int i=3; i>0; --i) {
+ for (int i = 3; i > 0; --i) {
// GX->uw[2 * i] = GX->uw[i];
- LHU(x3, gback, gdoffset+i*2);
- SH(x3, gback, gdoffset+2*i*2);
+ LHU(x3, gback, gdoffset + i * 2);
+ SH(x3, gback, gdoffset + 2 * i * 2);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
- for(int i=0; i<4; ++i) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+ for (int i = 0; i < 4; ++i) {
// GX->uw[2 * i + 1] = GX->uw[2 * i];
- LHU(x3, gback, gdoffset+2*i*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, gback, gdoffset + 2 * i * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
} else {
GETEX(x1, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->uw[2 * i + 1] = EX->uw[i];
- LHU(x3, wback, fixedaddress+i*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, wback, fixedaddress + i * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
}
break;
@@ -1308,14 +1415,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
// GX->ud[3] = EX->ud[1];
- LWU(x3, wback, fixedaddress+1*4);
- SW(x3, gback, gdoffset+3*4);
+ LWU(x3, wback, fixedaddress + 1 * 4);
+ SW(x3, gback, gdoffset + 3 * 4);
// GX->ud[2] = GX->ud[1];
- LWU(x3, gback, gdoffset+1*4);
- SW(x3, gback, gdoffset+2*4);
+ LWU(x3, gback, gdoffset + 1 * 4);
+ SW(x3, gback, gdoffset + 2 * 4);
// GX->ud[1] = EX->ud[0];
- LWU(x3, wback, fixedaddress+0*4);
- SW(x3, gback, gdoffset+1*4);
+ LWU(x3, wback, fixedaddress + 0 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
break;
case 0x63:
INST_NAME("PACKSSWB Gx, Ex");
@@ -1324,48 +1431,49 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
MOV64x(x5, 127);
MOV64x(x6, -128);
- for(int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+i*2);
- if(rv64_zbb) {
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + i * 2);
+ if (rv64_zbb) {
MIN(x3, x3, x5);
MAX(x3, x3, x6);
} else {
- BLT(x3, x5, 4+4);
+ BLT(x3, x5, 4 + 4);
MV(x3, x5);
- BGE(x3, x6, 4+4);
+ BGE(x3, x6, 4 + 4);
MV(x3, x6);
}
- SB(x3, gback, gdoffset+i);
- }
- if(MODREG && gd==ed) {
- LD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+8);
- } else for(int i=0; i<8; ++i) {
- LH(x3, wback, fixedaddress+i*2);
- if(rv64_zbb) {
- MIN(x3, x3, x5);
- MAX(x3, x3, x6);
- } else {
- BLT(x3, x5, 4+4);
- MV(x3, x5);
- BGE(x3, x6, 4+4);
- MV(x3, x6);
+ SB(x3, gback, gdoffset + i);
+ }
+ if (MODREG && gd == ed) {
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 8);
+ } else
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, wback, fixedaddress + i * 2);
+ if (rv64_zbb) {
+ MIN(x3, x3, x5);
+ MAX(x3, x3, x6);
+ } else {
+ BLT(x3, x5, 4 + 4);
+ MV(x3, x5);
+ BGE(x3, x6, 4 + 4);
+ MV(x3, x6);
+ }
+ SB(x3, gback, gdoffset + 8 + i);
}
- SB(x3, gback, gdoffset+8+i);
- }
break;
case 0x64:
INST_NAME("PCMPGTB Gx,Ex");
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
+ for (int i = 0; i < 16; ++i) {
// GX->ub[i] = (GX->sb[i]>EX->sb[i])?0xFF:0x00;
- LB(x3, wback, fixedaddress+i);
- LB(x4, gback, gdoffset+i);
+ LB(x3, wback, fixedaddress + i);
+ LB(x4, gback, gdoffset + i);
SLT(x3, x3, x4);
NEG(x3, x3);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0x65:
@@ -1373,13 +1481,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->uw[i] = (GX->sw[i]>EX->sw[i])?0xFFFF:0x0000;
- LH(x3, wback, fixedaddress+i*2);
- LH(x4, gback, gdoffset+i*2);
+ LH(x3, wback, fixedaddress + i * 2);
+ LH(x4, gback, gdoffset + i * 2);
SLT(x3, x3, x4);
NEG(x3, x3);
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
case 0x66:
@@ -1394,31 +1502,31 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
ADDI(x5, xZR, 0xFF);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[i] = (GX->sw[i]<0)?0:((GX->sw[i]>0xff)?0xff:GX->sw[i]);
- LH(x3, gback, gdoffset+i*2);
+ LH(x3, gback, gdoffset + i * 2);
BGE(x5, x3, 8);
ADDI(x3, xZR, 0xFF);
NOT(x4, x3);
SRAI(x4, x4, 63);
AND(x3, x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// GX->q[1] = GX->q[0];
- LD(x3, gback, gdoffset+0*8);
- SD(x3, gback, gdoffset+1*8);
+ LD(x3, gback, gdoffset + 0 * 8);
+ SD(x3, gback, gdoffset + 1 * 8);
} else {
GETEX(x1, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[8+i] = (EX->sw[i]<0)?0:((EX->sw[i]>0xff)?0xff:EX->sw[i]);
- LH(x3, wback, fixedaddress+i*2);
+ LH(x3, wback, fixedaddress + i * 2);
BGE(x5, x3, 8);
ADDI(x3, xZR, 0xFF);
NOT(x4, x3);
SRAI(x4, x4, 63);
AND(x3, x3, x4);
- SB(x3, gback, gdoffset+8+i);
+ SB(x3, gback, gdoffset + 8 + i);
}
}
break;
@@ -1426,23 +1534,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PUNPCKHBW Gx,Ex");
nextop = F8;
GETGX();
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[2 * i] = GX->ub[i + 8];
- LBU(x3, gback, gdoffset+i+8);
- SB(x3, gback, gdoffset+2*i);
+ LBU(x3, gback, gdoffset + i + 8);
+ SB(x3, gback, gdoffset + 2 * i);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
- for(int i=0; i<8; ++i) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[2 * i + 1] = GX->ub[2 * i];
- LBU(x3, gback, gdoffset+2*i);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, gback, gdoffset + 2 * i);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
} else {
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// GX->ub[2 * i + 1] = EX->ub[i + 8];
- LBU(x3, wback, fixedaddress+i+8);
- SB(x3, gback, gdoffset+2*i+1);
+ LBU(x3, wback, fixedaddress + i + 8);
+ SB(x3, gback, gdoffset + 2 * i + 1);
}
}
break;
@@ -1450,23 +1558,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PUNPCKHWD Gx,Ex");
nextop = F8;
GETGX();
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->uw[2 * i] = GX->uw[i + 4];
- LHU(x3, gback, gdoffset+(i+4)*2);
- SH(x3, gback, gdoffset+2*i*2);
+ LHU(x3, gback, gdoffset + (i + 4) * 2);
+ SH(x3, gback, gdoffset + 2 * i * 2);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
- for(int i=0; i<4; ++i) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+ for (int i = 0; i < 4; ++i) {
// GX->uw[2 * i + 1] = GX->uw[2 * i];
- LHU(x3, gback, gdoffset+2*i*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, gback, gdoffset + 2 * i * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
} else {
GETEX(x1, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->uw[2 * i + 1] = EX->uw[i + 4];
- LHU(x3, wback, fixedaddress+(i+4)*2);
- SH(x3, gback, gdoffset+(2*i+1)*2);
+ LHU(x3, wback, fixedaddress + (i + 4) * 2);
+ SH(x3, gback, gdoffset + (2 * i + 1) * 2);
}
}
break;
@@ -1476,18 +1584,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x1, 0);
GETGX();
// GX->ud[0] = GX->ud[2];
- LWU(x3, gback, gdoffset+2*4);
- SW(x3, gback, gdoffset+0*4);
+ LWU(x3, gback, gdoffset + 2 * 4);
+ SW(x3, gback, gdoffset + 0 * 4);
// GX->ud[1] = EX->ud[2];
- LWU(x3, wback, fixedaddress+2*4);
- SW(x3, gback, gdoffset+1*4);
+ LWU(x3, wback, fixedaddress + 2 * 4);
+ SW(x3, gback, gdoffset + 1 * 4);
// GX->ud[2] = GX->ud[3];
- LWU(x3, gback, gdoffset+3*4);
- SW(x3, gback, gdoffset+2*4);
+ LWU(x3, gback, gdoffset + 3 * 4);
+ SW(x3, gback, gdoffset + 2 * 4);
// GX->ud[3] = EX->ud[3];
- if (!(MODREG && (gd==ed))) {
- LWU(x3, wback, fixedaddress+3*4);
- SW(x3, gback, gdoffset+3*4);
+ if (!(MODREG && (gd == ed))) {
+ LWU(x3, wback, fixedaddress + 3 * 4);
+ SW(x3, gback, gdoffset + 3 * 4);
}
break;
case 0x6B:
@@ -1496,29 +1604,29 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
MOV64x(x5, 32768);
NEG(x6, x5);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->sw[i] = (GX->sd[i]<-32768)?-32768:((GX->sd[i]>32767)?32767:GX->sd[i]);
- LW(x3, gback, gdoffset+i*4);
+ LW(x3, gback, gdoffset + i * 4);
BGE(x5, x3, 8);
ADDI(x3, x5, -1);
BGE(x3, x6, 8);
MV(x3, x6);
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
- if (MODREG && gd==(nextop&7)+(rex.b<<3)) {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// GX->q[1] = GX->q[0];
- LD(x3, gback, gdoffset+0*8);
- SD(x3, gback, gdoffset+1*8);
+ LD(x3, gback, gdoffset + 0 * 8);
+ SD(x3, gback, gdoffset + 1 * 8);
} else {
GETEX(x1, 0);
- for(int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->sw[4+i] = (EX->sd[i]<-32768)?-32768:((EX->sd[i]>32767)?32767:EX->sd[i]);
- LW(x3, wback, fixedaddress+i*4);
+ LW(x3, wback, fixedaddress + i * 4);
BGE(x5, x3, 8);
ADDI(x3, x5, -1);
BGE(x3, x6, 8);
MV(x3, x6);
- SH(x3, gback, gdoffset+(4+i)*2);
+ SH(x3, gback, gdoffset + (4 + i) * 2);
}
}
break;
@@ -1526,13 +1634,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PUNPCKLQDQ Gx,Ex");
nextop = F8;
GETGX();
- if(MODREG) {
- v1 = sse_get_reg(dyn, ninst, x2, (nextop&7)+(rex.b<<3), 0);
- FSD(v1, gback, gdoffset+8);
+ if (MODREG) {
+ v1 = sse_get_reg(dyn, ninst, x2, (nextop & 7) + (rex.b << 3), 0);
+ FSD(v1, gback, gdoffset + 8);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
- LD(x3, ed, fixedaddress+0);
- SD(x3, gback, gdoffset+8);
+ LD(x3, ed, fixedaddress + 0);
+ SD(x3, gback, gdoffset + 8);
}
break;
case 0x6D:
@@ -1540,27 +1648,27 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- LD(x3, gback, gdoffset+8);
- SD(x3, gback, gdoffset+0);
- LD(x3, wback, fixedaddress+8);
- SD(x3, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 8);
+ SD(x3, gback, gdoffset + 0);
+ LD(x3, wback, fixedaddress + 8);
+ SD(x3, gback, gdoffset + 8);
break;
case 0x6E:
INST_NAME("MOVD Gx, Ed");
nextop = F8;
- if(rex.w) {
+ if (rex.w) {
GETGXSD_empty(v0);
} else {
GETGXSS_empty(v0);
}
GETED(0);
- if(rex.w) {
+ if (rex.w) {
FMVDX(v0, ed);
} else {
FMVWX(v0, ed);
- SW(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+4);
+ SW(xZR, xEmu, offsetof(x64emu_t, xmm[gd]) + 4);
}
- SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+8);
+ SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd]) + 8);
break;
case 0x6F:
INST_NAME("MOVDQA Gx,Ex");
@@ -1577,37 +1685,37 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
int32_t idx;
- idx = (u8>>(0*2))&3;
- LWU(x3, wback, fixedaddress+idx*4);
- idx = (u8>>(1*2))&3;
- LWU(x4, wback, fixedaddress+idx*4);
- idx = (u8>>(2*2))&3;
- LWU(x5, wback, fixedaddress+idx*4);
- idx = (u8>>(3*2))&3;
- LWU(x6, wback, fixedaddress+idx*4);
+ idx = (u8 >> (0 * 2)) & 3;
+ LWU(x3, wback, fixedaddress + idx * 4);
+ idx = (u8 >> (1 * 2)) & 3;
+ LWU(x4, wback, fixedaddress + idx * 4);
+ idx = (u8 >> (2 * 2)) & 3;
+ LWU(x5, wback, fixedaddress + idx * 4);
+ idx = (u8 >> (3 * 2)) & 3;
+ LWU(x6, wback, fixedaddress + idx * 4);
- SW(x3, gback, gdoffset+0*4);
- SW(x4, gback, gdoffset+1*4);
- SW(x5, gback, gdoffset+2*4);
- SW(x6, gback, gdoffset+3*4);
+ SW(x3, gback, gdoffset + 0 * 4);
+ SW(x4, gback, gdoffset + 1 * 4);
+ SW(x5, gback, gdoffset + 2 * 4);
+ SW(x6, gback, gdoffset + 3 * 4);
break;
case 0x71:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 2:
INST_NAME("PSRLW Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if (u8>15) {
+ if (u8 > 15) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
- } else if(u8) {
- for (int i=0; i<8; ++i) {
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
+ } else if (u8) {
+ for (int i = 0; i < 8; ++i) {
// EX->uw[i] >>= u8;
- LHU(x3, wback, fixedaddress+i*2);
+ LHU(x3, wback, fixedaddress + i * 2);
SRLI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -1615,13 +1723,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PSRAW Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(u8>15) u8=15;
- if(u8) {
- for (int i=0; i<8; ++i) {
+ if (u8 > 15) u8 = 15;
+ if (u8) {
+ for (int i = 0; i < 8; ++i) {
// EX->sw[i] >>= u8;
- LH(x3, wback, fixedaddress+i*2);
+ LH(x3, wback, fixedaddress + i * 2);
SRAI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -1629,16 +1737,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PSLLW Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if (u8>15) {
+ if (u8 > 15) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
- } else if(u8) {
- for (int i=0; i<8; ++i) {
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
+ } else if (u8) {
+ for (int i = 0; i < 8; ++i) {
// EX->uw[i] <<= u8;
- LHU(x3, wback, fixedaddress+i*2);
+ LHU(x3, wback, fixedaddress + i * 2);
SLLI(x3, x3, u8);
- SH(x3, wback, fixedaddress+i*2);
+ SH(x3, wback, fixedaddress + i * 2);
}
}
break;
@@ -1649,17 +1757,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0x72:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 2:
INST_NAME("PSRLD Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(u8) {
- if (u8>31) {
+ if (u8) {
+ if (u8 > 31) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
- } else if(u8) {
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
+ } else if (u8) {
SSE_LOOP_D_S(x3, SRLI(x3, x3, u8));
}
}
@@ -1668,7 +1776,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PSRAD Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(u8>31) u8=31;
+ if (u8 > 31) u8 = 31;
if (u8) {
SSE_LOOP_D_S(x3, SRAIW(x3, x3, u8));
}
@@ -1677,12 +1785,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PSLLD Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(u8) {
- if (u8>31) {
+ if (u8) {
+ if (u8 > 31) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
- } else if(u8) {
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
+ } else if (u8) {
SSE_LOOP_D_S(x3, SLLI(x3, x3, u8));
}
}
@@ -1693,50 +1801,50 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
break;
case 0x73:
nextop = F8;
- switch((nextop>>3)&7) {
+ switch ((nextop >> 3) & 7) {
case 2:
INST_NAME("PSRLQ Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(!u8) break;
- if(u8>63) {
+ if (!u8) break;
+ if (u8 > 63) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
} else {
- LD(x3, wback, fixedaddress+0);
- LD(x4, wback, fixedaddress+8);
+ LD(x3, wback, fixedaddress + 0);
+ LD(x4, wback, fixedaddress + 8);
SRLI(x3, x3, u8);
SRLI(x4, x4, u8);
- SD(x3, wback, fixedaddress+0);
- SD(x4, wback, fixedaddress+8);
+ SD(x3, wback, fixedaddress + 0);
+ SD(x4, wback, fixedaddress + 8);
}
break;
case 3:
INST_NAME("PSRLDQ Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(!u8) break;
- if(u8>15) {
+ if (!u8) break;
+ if (u8 > 15) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
} else {
- u8*=8;
+ u8 *= 8;
if (u8 < 64) {
- LD(x3, wback, fixedaddress+0);
- LD(x4, wback, fixedaddress+8);
+ LD(x3, wback, fixedaddress + 0);
+ LD(x4, wback, fixedaddress + 8);
SRLI(x3, x3, u8);
- SLLI(x5, x4, 64-u8);
+ SLLI(x5, x4, 64 - u8);
OR(x3, x3, x5);
- SD(x3, wback, fixedaddress+0);
+ SD(x3, wback, fixedaddress + 0);
SRLI(x4, x4, u8);
- SD(x4, wback, fixedaddress+8);
+ SD(x4, wback, fixedaddress + 8);
} else {
- LD(x3, wback, fixedaddress+8);
- if (u8-64 > 0) { SRLI(x3, x3, u8-64); }
- SD(x3, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
+ LD(x3, wback, fixedaddress + 8);
+ if (u8 - 64 > 0) { SRLI(x3, x3, u8 - 64); }
+ SD(x3, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
}
}
break;
@@ -1744,45 +1852,45 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PSLLQ Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(!u8) break;
- if(u8>63) {
+ if (!u8) break;
+ if (u8 > 63) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
} else {
- LD(x3, wback, fixedaddress+0);
- LD(x4, wback, fixedaddress+8);
+ LD(x3, wback, fixedaddress + 0);
+ LD(x4, wback, fixedaddress + 8);
SLLI(x3, x3, u8);
SLLI(x4, x4, u8);
- SD(x3, wback, fixedaddress+0);
- SD(x4, wback, fixedaddress+8);
+ SD(x3, wback, fixedaddress + 0);
+ SD(x4, wback, fixedaddress + 8);
}
break;
case 7:
INST_NAME("PSLLDQ Ex, Ib");
GETEX(x1, 1);
u8 = F8;
- if(!u8) break;
- if(u8>15) {
+ if (!u8) break;
+ if (u8 > 15) {
// just zero dest
- SD(xZR, wback, fixedaddress+0);
- SD(xZR, wback, fixedaddress+8);
+ SD(xZR, wback, fixedaddress + 0);
+ SD(xZR, wback, fixedaddress + 8);
} else {
- u8*=8;
+ u8 *= 8;
if (u8 < 64) {
- LD(x3, wback, fixedaddress+0);
- LD(x4, wback, fixedaddress+8);
+ LD(x3, wback, fixedaddress + 0);
+ LD(x4, wback, fixedaddress + 8);
SLLI(x4, x4, u8);
- SRLI(x5, x3, 64-u8);
+ SRLI(x5, x3, 64 - u8);
OR(x4, x4, x5);
- SD(x4, wback, fixedaddress+8);
+ SD(x4, wback, fixedaddress + 8);
SLLI(x3, x3, u8);
- SD(x3, wback, fixedaddress+0);
+ SD(x3, wback, fixedaddress + 0);
} else {
- LD(x3, wback, fixedaddress+0);
- if (u8-64 > 0) { SLLI(x3, x3, u8-64); }
- SD(x3, wback, fixedaddress+8);
- SD(xZR, wback, fixedaddress+0);
+ LD(x3, wback, fixedaddress + 0);
+ if (u8 - 64 > 0) { SLLI(x3, x3, u8 - 64); }
+ SD(x3, wback, fixedaddress + 8);
+ SD(xZR, wback, fixedaddress + 0);
}
}
break;
@@ -1795,13 +1903,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
SUB(x3, x3, x4);
SEQZ(x3, x3);
NEG(x3, x3);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0x75:
@@ -1824,63 +1932,63 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
- FLD(d0, gback, gdoffset+0);
- FLD(d1, gback, gdoffset+8);
- if(!box64_dynarec_fastnan) {
+ FLD(d0, gback, gdoffset + 0);
+ FLD(d1, gback, gdoffset + 8);
+ if (!box64_dynarec_fastnan) {
FEQD(x3, d0, d0);
FEQD(x4, d1, d1);
AND(x3, x3, x4);
}
FADDD(d0, d0, d1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x4, d0, d0);
BEQZ(x3, 12);
BNEZ(x4, 8);
FNEGD(d0, d0);
}
- FSD(d0, gback, gdoffset+0);
- if(MODREG && gd==(nextop&7)+(rex.b<<3)) {
- FSD(d0, gback, gdoffset+8);
+ FSD(d0, gback, gdoffset + 0);
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
+ FSD(d0, gback, gdoffset + 8);
} else {
GETEX(x2, 0);
- FLD(d0, wback, fixedaddress+0);
- FLD(d1, wback, fixedaddress+8);
- if(!box64_dynarec_fastnan) {
+ FLD(d0, wback, fixedaddress + 0);
+ FLD(d1, wback, fixedaddress + 8);
+ if (!box64_dynarec_fastnan) {
FEQD(x3, d0, d0);
FEQD(x4, d1, d1);
AND(x3, x3, x4);
}
FADDD(d0, d0, d1);
- if(!box64_dynarec_fastnan) {
+ if (!box64_dynarec_fastnan) {
FEQD(x4, d0, d0);
BEQZ(x3, 12);
BNEZ(x4, 8);
FNEGD(d0, d0);
}
- FSD(d0, gback, gdoffset+8);
+ FSD(d0, gback, gdoffset + 8);
}
break;
case 0x7E:
INST_NAME("MOVD Ed,Gx");
nextop = F8;
GETGX();
- if(rex.w) {
- if(MODREG) {
- ed = xRAX + (nextop&7) + (rex.b<<3);
- LD(ed, gback, gdoffset+0);
+ if (rex.w) {
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ LD(ed, gback, gdoffset + 0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
- LD(x3, gback, gdoffset+0);
+ LD(x3, gback, gdoffset + 0);
SD(x3, ed, fixedaddress);
SMWRITE2();
}
} else {
- if(MODREG) {
- ed = xRAX + (nextop&7) + (rex.b<<3);
- LWU(ed, gback, gdoffset+0);
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ LWU(ed, gback, gdoffset + 0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
- LWU(x3, gback, gdoffset+0);
+ LWU(x3, gback, gdoffset + 0);
SW(x3, ed, fixedaddress);
SMWRITE2();
}
@@ -1892,7 +2000,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
SSE_LOOP_MV_Q2(x3);
- if(!MODREG) SMWRITE2();
+ if (!MODREG) SMWRITE2();
break;
case 0xAF:
INST_NAME("IMUL Gw,Ew");
@@ -1906,22 +2014,47 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
ZEXTH(x2, x2);
GWBACK;
break;
-
+ case 0xB6:
+ INST_NAME("MOVZX Gw, Eb");
+ nextop = F8;
+ if (MODREG) {
+ if (rex.rex) {
+ eb1 = xRAX + (nextop & 7) + (rex.b << 3);
+ eb2 = 0;
+ } else {
+ ed = (nextop & 7);
+ eb1 = xRAX + (ed & 3); // Ax, Cx, Dx or Bx
+ eb2 = (ed & 4) >> 2; // L or H
+ }
+ if (eb2) {
+ SRLI(x1, eb1, 8);
+ eb1 = x1;
+ }
+ ANDI(x1, eb1, 0xff);
+ } else {
+ SMREAD();
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0);
+ LBU(x1, ed, fixedaddress);
+ }
+ LUI(x5, 0xffff0);
+ AND(gd, gd, x5);
+ OR(gd, gd, x1);
+ break;
case 0xBE:
INST_NAME("MOVSX Gw, Eb");
nextop = F8;
GETGD;
- if(MODREG) {
- if(rex.rex) {
- ed = xRAX+(nextop&7)+(rex.b<<3);
- eb1=ed;
- eb2=0;
+ if (MODREG) {
+ if (rex.rex) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ eb1 = ed;
+ eb2 = 0;
} else {
- ed = (nextop&7);
- eb1 = xRAX+(ed&3); // Ax, Cx, Dx or Bx
- eb2 = (ed&4)>>2; // L or H
+ ed = (nextop & 7);
+ eb1 = xRAX + (ed & 3); // Ax, Cx, Dx or Bx
+ eb2 = (ed & 4) >> 2; // L or H
}
- SLLI(x1, eb1, 56-eb2*8);
+ SLLI(x1, eb1, 56 - eb2 * 8);
SRAI(x1, x1, 56);
} else {
SMREAD();
@@ -1942,12 +2075,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
d0 = fpu_get_scratch(dyn);
d1 = fpu_get_scratch(dyn);
- for(int i=0; i<2; ++i) {
- FLD(d0, gback, gdoffset+8*i);
- FLD(d1, wback, fixedaddress+8*i);
- if ((u8&7) == 0) { // Equal
+ for (int i = 0; i < 2; ++i) {
+ FLD(d0, gback, gdoffset + 8 * i);
+ FLD(d1, wback, fixedaddress + 8 * i);
+ if ((u8 & 7) == 0) { // Equal
FEQD(x3, d0, d1);
- } else if ((u8&7) == 4) { // Not Equal or unordered
+ } else if ((u8 & 7) == 4) { // Not Equal or unordered
FEQD(x3, d0, d1);
XORI(x3, x3, 1);
} else {
@@ -1956,33 +2089,39 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
FEQD(x3, d1, d1);
AND(x3, x3, x4);
- switch(u8&7) {
- case 1: BEQ_MARK(x3, xZR); FLTD(x3, d0, d1); break; // Less than
- case 2: BEQ_MARK(x3, xZR); FLED(x3, d0, d1); break; // Less or equal
- case 3: XORI(x3, x3, 1); break; // NaN
- case 5: { // Greater or equal or unordered
- BEQ(x3, xZR, 12); // MARK2
- FLED(x3, d1, d0);
- J(8); // MARK;
- break;
- }
- case 6: { // Greater or unordered
- BEQ(x3, xZR, 12); // MARK2
- FLTD(x3, d1, d0);
- J(8); // MARK;
- break;
- }
- case 7: break; // Not NaN
+ switch (u8 & 7) {
+ case 1:
+ BEQ_MARK(x3, xZR);
+ FLTD(x3, d0, d1);
+ break; // Less than
+ case 2:
+ BEQ_MARK(x3, xZR);
+ FLED(x3, d0, d1);
+ break; // Less or equal
+ case 3: XORI(x3, x3, 1); break; // NaN
+ case 5: { // Greater or equal or unordered
+ BEQ(x3, xZR, 12); // MARK2
+ FLED(x3, d1, d0);
+ J(8); // MARK;
+ break;
+ }
+ case 6: { // Greater or unordered
+ BEQ(x3, xZR, 12); // MARK2
+ FLTD(x3, d1, d0);
+ J(8); // MARK;
+ break;
+ }
+ case 7: break; // Not NaN
}
// MARK2;
- if ((u8&7) == 5 || (u8&7) == 6) {
+ if ((u8 & 7) == 5 || (u8 & 7) == 6) {
MOV32w(x3, 1);
}
// MARK;
}
NEG(x3, x3);
- SD(x3, gback, gdoffset+8*i);
+ SD(x3, gback, gdoffset + 8 * i);
}
break;
case 0xC4:
@@ -1991,7 +2130,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETED(1);
GETGX();
u8 = (F8)&7;
- SH(ed, gback, gdoffset+u8*2);
+ SH(ed, gback, gdoffset + u8 * 2);
break;
case 0xC5:
INST_NAME("PEXTRW Gd,Ex,Ib");
@@ -1999,7 +2138,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGD;
GETEX(x1, 0);
u8 = (F8)&7;
- LHU(gd, wback, fixedaddress+u8*2);
+ LHU(gd, wback, fixedaddress + u8 * 2);
break;
case 0xC6:
INST_NAME("SHUFPD Gx, Ex, Ib");
@@ -2007,15 +2146,15 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 1);
u8 = F8;
- if (MODREG && gd==(nextop&7)+(rex.b<<3) && u8==0) {
- LD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+8);
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3) && u8 == 0) {
+ LD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 8);
break;
}
- LD(x3, gback, gdoffset+8*(u8&1));
- LD(x4, wback, fixedaddress+8*((u8>>1)&1));
- SD(x3, gback, gdoffset+0);
- SD(x4, gback, gdoffset+8);
+ LD(x3, gback, gdoffset + 8 * (u8 & 1));
+ LD(x4, wback, fixedaddress + 8 * ((u8 >> 1) & 1));
+ SD(x3, gback, gdoffset + 0);
+ SD(x4, gback, gdoffset + 8);
break;
case 0xD1:
INST_NAME("PSRLW Gx,Ex");
@@ -2025,14 +2164,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LD(x3, wback, fixedaddress);
ADDI(x4, xZR, 16);
BLTU_MARK(x3, x4);
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<8; ++i) {
- LHU(x5, gback, gdoffset+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x5, gback, gdoffset + 2 * i);
SRLW(x5, x5, x3);
- SH(x5, gback, gdoffset+2*i);
+ SH(x5, gback, gdoffset + 2 * i);
}
break;
case 0xD2:
@@ -2043,14 +2182,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LD(x3, wback, fixedaddress);
ADDI(x4, xZR, 32);
BLTU_MARK(x3, x4);
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<4; ++i) {
- LWU(x5, gback, gdoffset+4*i);
+ for (int i = 0; i < 4; ++i) {
+ LWU(x5, gback, gdoffset + 4 * i);
SRLW(x5, x5, x3);
- SW(x5, gback, gdoffset+4*i);
+ SW(x5, gback, gdoffset + 4 * i);
}
break;
case 0xD3:
@@ -2061,14 +2200,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LD(x3, wback, fixedaddress);
ADDI(x4, xZR, 64);
BLTU_MARK(x3, x4);
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<2; ++i) {
- LD(x5, gback, gdoffset+8*i);
+ for (int i = 0; i < 2; ++i) {
+ LD(x5, gback, gdoffset + 8 * i);
SRL(x5, x5, x3);
- SD(x5, gback, gdoffset+8*i);
+ SD(x5, gback, gdoffset + 8 * i);
}
break;
case 0xD4:
@@ -2083,11 +2222,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
MULW(x3, x3, x4);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xD6:
@@ -2095,9 +2234,9 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGXSD(d0);
GETEX(x2, 0);
- FSD(d0, wback, fixedaddress+0);
+ FSD(d0, wback, fixedaddress + 0);
if (MODREG) {
- SD(xZR, wback, fixedaddress+8);
+ SD(xZR, wback, fixedaddress + 8);
} else {
SMWRITE2();
}
@@ -2108,8 +2247,8 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
GETGD;
MV(gd, xZR);
- for (int i=0; i<16; ++i) {
- LB(x1, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LB(x1, wback, fixedaddress + i);
SLT(x3, x1, xZR);
if (i > 0) SLLI(x3, x3, i);
OR(gd, gd, x3);
@@ -2120,14 +2259,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
SUB(x3, x3, x4);
NOT(x4, x3);
SRAI(x4, x4, 63);
AND(x3, x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xD9:
@@ -2142,12 +2281,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
BLTU(x3, x4, 8);
MV(x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xDB:
@@ -2163,13 +2302,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
ADDI(x5, xZR, 0xFF);
- for(int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
ADD(x3, x3, x4);
BLT(x3, x5, 8);
ADDI(x3, xZR, 0xFF);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xDD:
@@ -2177,16 +2316,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// tmp32s = (int32_t)GX->uw[i] + EX->uw[i];
// GX->uw[i] = (tmp32s>65535)?65535:tmp32s;
- LHU(x3, gback, gdoffset+i*2);
- LHU(x4, wback, fixedaddress+i*2);
+ LHU(x3, gback, gdoffset + i * 2);
+ LHU(x4, wback, fixedaddress + i * 2);
ADDW(x3, x3, x4);
MOV32w(x4, 65536);
BLT(x3, x4, 8);
ADDIW(x3, x4, -1);
- SH(x3, gback, gdoffset+i*2);
+ SH(x3, gback, gdoffset + i * 2);
}
break;
case 0xDE:
@@ -2194,12 +2333,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
BLTU(x4, x3, 8);
MV(x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xDF:
@@ -2209,18 +2348,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
SSE_LOOP_Q(x3, x4, NOT(x3, x3); AND(x3, x3, x4));
break;
- case 0xE0:
+ case 0xE0:
INST_NAME("PAVGB Gx, Ex");
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
ADDW(x3, x3, x4);
ADDIW(x3, x3, 1);
SRAIW(x3, x3, 1);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xE1:
@@ -2232,10 +2371,10 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LD(x3, wback, fixedaddress);
BLTU(x3, x4, 8);
SUBI(x3, x4, 1);
- for (int i=0; i<8; ++i) {
- LH(x4, gback, gdoffset+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LH(x4, gback, gdoffset + 2 * i);
SRAW(x4, x4, x3);
- SH(x4, gback, gdoffset+2*i);
+ SH(x4, gback, gdoffset + 2 * i);
}
break;
case 0xE2:
@@ -2247,10 +2386,10 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
LD(x3, wback, fixedaddress);
BLTU(x3, x4, 8);
SUBI(x3, x4, 1);
- for (int i=0; i<4; ++i) {
- LW(x4, gback, gdoffset+4*i);
+ for (int i = 0; i < 4; ++i) {
+ LW(x4, gback, gdoffset + 4 * i);
SRAW(x4, x4, x3);
- SW(x4, gback, gdoffset+4*i);
+ SW(x4, gback, gdoffset + 4 * i);
}
break;
case 0xE3:
@@ -2258,13 +2397,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<8; ++i) {
- LHU(x3, gback, gdoffset+2*i);
- LHU(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x3, gback, gdoffset + 2 * i);
+ LHU(x4, wback, fixedaddress + 2 * i);
ADDW(x3, x3, x4);
ADDIW(x3, x3, 1);
SRAIW(x3, x3, 1);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xE4:
@@ -2272,12 +2411,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LHU(x3, gback, gdoffset+2*i);
- LHU(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x3, gback, gdoffset + 2 * i);
+ LHU(x4, wback, fixedaddress + 2 * i);
MULW(x3, x3, x4);
SRLIW(x3, x3, 16);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xE5:
@@ -2285,12 +2424,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
MULW(x3, x3, x4);
SRAIW(x3, x3, 16);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xE6:
@@ -2300,31 +2439,31 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
v0 = fpu_get_scratch(dyn);
v1 = fpu_get_scratch(dyn);
- FLD(v0, wback, fixedaddress+0);
- FLD(v1, wback, fixedaddress+8);
- if(!box64_dynarec_fastround) {
- FSFLAGSI(0); // // reset all bits
+ FLD(v0, wback, fixedaddress + 0);
+ FLD(v1, wback, fixedaddress + 8);
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
}
FCVTWD(x3, v0, RD_RTZ);
- if(!box64_dynarec_fastround) {
- FRFLAGS(x5); // get back FPSR to check the IOC bit
- ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF));
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
BEQ_MARK(x5, xZR);
MOV32w(x3, 0x80000000);
MARK;
- FSFLAGSI(0); // // reset all bits
+ FSFLAGSI(0); // // reset all bits
}
FCVTWD(x4, v1, RD_RTZ);
- if(!box64_dynarec_fastround) {
- FRFLAGS(x5); // get back FPSR to check the IOC bit
- ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF));
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
BEQ_MARK2(x5, xZR);
MOV32w(x4, 0x80000000);
MARK2;
}
- SW(x3, gback, gdoffset+0);
- SW(x4, gback, gdoffset+4);
- SD(xZR, gback, gdoffset+8);
+ SW(x3, gback, gdoffset + 0);
+ SW(x4, gback, gdoffset + 4);
+ SD(xZR, gback, gdoffset + 8);
break;
case 0xE7:
INST_NAME("MOVNTDQ Ex, Gx");
@@ -2338,23 +2477,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
+ for (int i = 0; i < 16; ++i) {
// tmp16s = (int16_t)GX->sb[i] - EX->sb[i];
// GX->sb[i] = (tmp16s<-128)?-128:((tmp16s>127)?127:tmp16s);
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
SUBW(x3, x3, x4);
SLLIW(x3, x3, 16);
SRAIW(x3, x3, 16);
ADDI(x4, xZR, 0x7f);
- BLT(x3, x4, 12); // tmp16s>127?
- SB(x4, gback, gdoffset+i);
- J(24); // continue
+ BLT(x3, x4, 12); // tmp16s>127?
+ SB(x4, gback, gdoffset + i);
+ J(24); // continue
ADDI(x4, xZR, 0xf80);
- BLT(x4, x3, 12); // tmp16s<-128?
- SB(x4, gback, gdoffset+i);
- J(8); // continue
- SB(x3, gback, gdoffset+i);
+ BLT(x4, x3, 12); // tmp16s<-128?
+ SB(x4, gback, gdoffset + i);
+ J(8); // continue
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xE9:
@@ -2362,20 +2501,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// tmp32s = (int32_t)GX->sw[i] - EX->sw[i];
// GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
SUBW(x3, x3, x4);
LUI(x4, 0xFFFF8); // -32768
BGE(x3, x4, 12);
- SH(x4, gback, gdoffset+2*i);
- J(20); // continue
+ SH(x4, gback, gdoffset + 2 * i);
+ J(20); // continue
LUI(x4, 8); // 32768
BLT(x3, x4, 8);
ADDIW(x3, x4, -1);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xEA:
@@ -2383,12 +2522,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<8; ++i) {
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
BLT(x3, x4, 8);
MV(x3, x4);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xEB:
@@ -2403,23 +2542,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
+ for (int i = 0; i < 16; ++i) {
// tmp16s = (int16_t)GX->sb[i] + EX->sb[i];
// GX->sb[i] = (tmp16s>127)?127:((tmp16s<-128)?-128:tmp16s);
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
ADDW(x3, x3, x4);
SLLIW(x3, x3, 16);
SRAIW(x3, x3, 16);
ADDI(x4, xZR, 0x7f);
- BLT(x3, x4, 12); // tmp16s>127?
- SB(x4, gback, gdoffset+i);
- J(24); // continue
+ BLT(x3, x4, 12); // tmp16s>127?
+ SB(x4, gback, gdoffset + i);
+ J(24); // continue
ADDI(x4, xZR, 0xf80);
- BLT(x4, x3, 12); // tmp16s<-128?
- SB(x4, gback, gdoffset+i);
- J(8); // continue
- SB(x3, gback, gdoffset+i);
+ BLT(x4, x3, 12); // tmp16s<-128?
+ SB(x4, gback, gdoffset + i);
+ J(8); // continue
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xED:
@@ -2427,20 +2566,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<8; ++i) {
+ for (int i = 0; i < 8; ++i) {
// tmp32s = (int32_t)GX->sw[i] + EX->sw[i];
// GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
- LH(x3, gback, gdoffset+2*i);
- LH(x4, wback, fixedaddress+2*i);
+ LH(x3, gback, gdoffset + 2 * i);
+ LH(x4, wback, fixedaddress + 2 * i);
ADDW(x3, x3, x4);
LUI(x4, 0xFFFF8); // -32768
BGE(x3, x4, 12);
- SH(x4, gback, gdoffset+2*i);
- J(20); // continue
+ SH(x4, gback, gdoffset + 2 * i);
+ J(20); // continue
LUI(x4, 8); // 32768
BLT(x3, x4, 8);
ADDIW(x3, x4, -1);
- SH(x3, gback, gdoffset+2*i);
+ SH(x3, gback, gdoffset + 2 * i);
}
break;
case 0xEE:
@@ -2454,11 +2593,10 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
INST_NAME("PXOR Gx, Ex");
nextop = F8;
GETGX();
- if(MODREG && gd==(nextop&7)+(rex.b<<3))
- {
+ if (MODREG && gd == (nextop & 7) + (rex.b << 3)) {
// just zero dest
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
} else {
GETEX(x2, 0);
SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
@@ -2470,17 +2608,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
ADDI(x4, xZR, 16);
- LD(x3, wback, fixedaddress+0);
+ LD(x3, wback, fixedaddress + 0);
BLTU_MARK(x3, x4);
// just zero dest
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<8; ++i) {
- LHU(x4, gback, gdoffset+2*i);
+ for (int i = 0; i < 8; ++i) {
+ LHU(x4, gback, gdoffset + 2 * i);
SLLW(x4, x4, x3);
- SH(x4, gback, gdoffset+2*i);
+ SH(x4, gback, gdoffset + 2 * i);
}
break;
case 0xF2:
@@ -2489,17 +2627,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
ADDI(x4, xZR, 32);
- LD(x3, wback, fixedaddress+0);
+ LD(x3, wback, fixedaddress + 0);
BLTU_MARK(x3, x4);
// just zero dest
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<4; ++i) {
- LWU(x4, gback, gdoffset+4*i);
+ for (int i = 0; i < 4; ++i) {
+ LWU(x4, gback, gdoffset + 4 * i);
SLLW(x4, x4, x3);
- SW(x4, gback, gdoffset+4*i);
+ SW(x4, gback, gdoffset + 4 * i);
}
break;
case 0xF3:
@@ -2508,17 +2646,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
ADDI(x4, xZR, 64);
- LD(x3, wback, fixedaddress+0);
+ LD(x3, wback, fixedaddress + 0);
BLTU_MARK(x3, x4);
// just zero dest
- SD(xZR, gback, gdoffset+0);
- SD(xZR, gback, gdoffset+8);
+ SD(xZR, gback, gdoffset + 0);
+ SD(xZR, gback, gdoffset + 8);
B_NEXT_nocond;
MARK;
- for (int i=0; i<2; ++i) {
- LD(x4, gback, gdoffset+8*i);
+ for (int i = 0; i < 2; ++i) {
+ LD(x4, gback, gdoffset + 8 * i);
SLL(x4, x4, x3);
- SD(x4, gback, gdoffset+8*i);
+ SD(x4, gback, gdoffset + 8 * i);
}
break;
case 0xF4:
@@ -2527,32 +2665,32 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
// GX->q[1] = (uint64_t)EX->ud[2]*GX->ud[2];
- LWU(x3, gback, gdoffset+2*4);
- LWU(x4, wback, fixedaddress+2*4);
+ LWU(x3, gback, gdoffset + 2 * 4);
+ LWU(x4, wback, fixedaddress + 2 * 4);
MUL(x3, x3, x4);
- SD(x3, gback, gdoffset+8);
+ SD(x3, gback, gdoffset + 8);
// GX->q[0] = (uint64_t)EX->ud[0]*GX->ud[0];
- LWU(x3, gback, gdoffset+0*4);
- LWU(x4, wback, fixedaddress+0*4);
+ LWU(x3, gback, gdoffset + 0 * 4);
+ LWU(x4, wback, fixedaddress + 0 * 4);
MUL(x3, x3, x4);
- SD(x3, gback, gdoffset+0);
+ SD(x3, gback, gdoffset + 0);
break;
case 0xF5:
INST_NAME("PMADDWD Gx, Ex");
nextop = F8;
GETGX();
GETEX(x2, 0);
- for (int i=0; i<4; ++i) {
+ for (int i = 0; i < 4; ++i) {
// GX->sd[i] = (int32_t)(GX->sw[i*2+0])*EX->sw[i*2+0] +
// (int32_t)(GX->sw[i*2+1])*EX->sw[i*2+1];
- LH(x3, gback, gdoffset+2*(i*2+0));
- LH(x4, wback, fixedaddress+2*(i*2+0));
+ LH(x3, gback, gdoffset + 2 * (i * 2 + 0));
+ LH(x4, wback, fixedaddress + 2 * (i * 2 + 0));
MULW(x5, x3, x4);
- LH(x3, gback, gdoffset+2*(i*2+1));
- LH(x4, wback, fixedaddress+2*(i*2+1));
+ LH(x3, gback, gdoffset + 2 * (i * 2 + 1));
+ LH(x4, wback, fixedaddress + 2 * (i * 2 + 1));
MULW(x6, x3, x4);
ADDW(x5, x5, x6);
- SW(x5, gback, gdoffset+4*i);
+ SW(x5, gback, gdoffset + 4 * i);
}
break;
case 0xF6:
@@ -2561,18 +2699,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
MV(x6, xZR);
- for (int i=0; i<16; ++i) {
- LBU(x3, gback, gdoffset+i);
- LBU(x4, wback, fixedaddress+i);
+ for (int i = 0; i < 16; ++i) {
+ LBU(x3, gback, gdoffset + i);
+ LBU(x4, wback, fixedaddress + i);
SUBW(x3, x3, x4);
SRAIW(x5, x3, 31);
XOR(x3, x5, x3);
SUBW(x3, x3, x5);
ANDI(x3, x3, 0xff);
ADDW(x6, x6, x3);
- if (i==7 || i == 15) {
- SD(x6, gback, gdoffset+i+1-8);
- if (i==7) MV(x6, xZR);
+ if (i == 7 || i == 15) {
+ SD(x6, gback, gdoffset + i + 1 - 8);
+ if (i == 7) MV(x6, xZR);
}
}
break;
@@ -2581,12 +2719,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
+ for (int i = 0; i < 16; ++i) {
// GX->sb[i] -= EX->sb[i];
- LB(x3, wback, fixedaddress+i);
- LB(x4, gback, gdoffset+i);
+ LB(x3, wback, fixedaddress + i);
+ LB(x4, gback, gdoffset + i);
SUB(x3, x4, x3);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xF9:
@@ -2615,12 +2753,12 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGX();
GETEX(x2, 0);
- for(int i=0; i<16; ++i) {
+ for (int i = 0; i < 16; ++i) {
// GX->sb[i] += EX->sb[i];
- LB(x3, gback, gdoffset+i);
- LB(x4, wback, fixedaddress+i);
+ LB(x3, gback, gdoffset + i);
+ LB(x4, wback, fixedaddress + i);
ADDW(x3, x3, x4);
- SB(x3, gback, gdoffset+i);
+ SB(x3, gback, gdoffset + i);
}
break;
case 0xFD:
diff --git a/src/dynarec/rv64/dynarec_rv64_66f20f.c b/src/dynarec/rv64/dynarec_rv64_66f20f.c
new file mode 100644
index 0000000..cf377f4
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_66f20f.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_functions.h"
+#include "dynarec_rv64_helper.h"
+
+uintptr_t dynarec64_66F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+ (void)ip;
+ (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop, u8, s8;
+ int32_t i32;
+ uint8_t gd, ed;
+ uint8_t wback, wb1, wb2, gback;
+ uint8_t eb1, eb2;
+ int64_t j64;
+ uint64_t tmp64u, tmp64u2;
+ int v0, v1;
+ int q0, q1;
+ int d0, d1;
+ int64_t fixedaddress, gdoffset;
+ int unscaled;
+
+ MAYUSE(d0);
+ MAYUSE(d1);
+ MAYUSE(q0);
+ MAYUSE(q1);
+ MAYUSE(eb1);
+ MAYUSE(eb2);
+ MAYUSE(j64);
+
+ static const int8_t round_round[] = { RD_RNE, RD_RDN, RD_RUP, RD_RTZ };
+
+ switch (opcode) {
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_66f30f.c b/src/dynarec/rv64/dynarec_rv64_66f30f.c
new file mode 100644
index 0000000..50b4e4a
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_66f30f.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_functions.h"
+#include "dynarec_rv64_helper.h"
+
+uintptr_t dynarec64_66F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+ (void)ip;
+ (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop, u8, s8;
+ int32_t i32;
+ uint8_t gd, ed;
+ uint8_t wback, wb1, wb2, gback;
+ uint8_t eb1, eb2;
+ int64_t j64;
+ uint64_t tmp64u, tmp64u2;
+ int v0, v1;
+ int q0, q1;
+ int d0, d1;
+ int64_t fixedaddress, gdoffset;
+ int unscaled;
+
+ MAYUSE(d0);
+ MAYUSE(d1);
+ MAYUSE(q0);
+ MAYUSE(q1);
+ MAYUSE(eb1);
+ MAYUSE(eb2);
+ MAYUSE(j64);
+
+ static const int8_t round_round[] = { RD_RNE, RD_RDN, RD_RUP, RD_RTZ };
+
+ switch (opcode) {
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index 5f10274..2ede9c3 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -180,6 +180,44 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
DEFAULT;
}
break;
+ case 0xB6:
+ INST_NAME("MOVXZ Gd, Eb");
+ nextop = F8;
+ GETGD;
+ if(MODREG) {
+ if (rex.rex) {
+ eb1 = xRAX + (nextop & 7) + (rex.b << 3);
+ eb2 = 0;
+ } else {
+ ed = (nextop & 7);
+ eb1 = xRAX + (ed & 3); // Ax, Cx, Dx or Bx
+ eb2 = (ed & 4) >> 2; // L or H
+ }
+ if (eb2) {
+ SRLI(gd, eb1, 8);
+ ANDI(gd, gd, 0xff);
+ } else {
+ ANDI(gd, eb1, 0xff);
+ }
+ } else {
+ SMREAD();
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ LBU(gd, ed, fixedaddress);
+ }
+ break;
+ case 0xB7:
+ INST_NAME("MOVZX Gd, Ew");
+ nextop = F8;
+ GETGD;
+ if(MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ ZEXTH(gd, ed);
+ } else {
+ SMREAD();
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ LHU(gd, ed, fixedaddress);
+ }
+ break;
default:
DEFAULT;
}
@@ -410,6 +448,54 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else
emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4);
break;
+ case 0x63:
+ INST_NAME("MOVSXD Gd, Ed");
+ nextop = F8;
+ GETGD;
+ if (rex.w) {
+ if (MODREG) { // reg <= reg
+ ADDIW(gd, xRAX + (nextop & 7) + (rex.b << 3), 0);
+ } else { // mem <= reg
+ SMREAD();
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ LW(gd, ed, fixedaddress);
+ }
+ } else {
+ if (MODREG) { // reg <= reg
+ AND(gd, xRAX + (nextop & 7) + (rex.b << 3), xMASK);
+ } else { // mem <= reg
+ SMREAD();
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ LWU(gd, ed, fixedaddress);
+ }
+ }
+ break;
+ case 0x66:
+ opcode = F8;
+ switch (opcode) {
+ case 0x89:
+ INST_NAME("MOV Ew, Gw");
+ nextop = F8;
+ GETGD; // don't need GETGW here
+ if (MODREG) {
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ if (ed != gd) {
+ LUI(x1, 0xffff0);
+ AND(ed, ed, x1);
+ ZEXTH(x2, gd);
+ OR(ed, ed, x2);
+ }
+ } else {
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ SH(gd, ed, fixedaddress);
+ SMWRITELOCK(lock);
+ }
+ break;
+
+ default:
+ DEFAULT;
+ }
+ break;
case 0x81:
case 0x83:
@@ -567,6 +653,23 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
}
break;
+
+ case 0xC7:
+ INST_NAME("MOV Ed, Id");
+ nextop = F8;
+ if(MODREG) { // reg <= i32
+ i64 = F32S;
+ ed = xRAX + (nextop & 7) + (rex.b << 3);
+ MOV64xw(ed, i64);
+ } else { // mem <= i32
+ addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+ i64 = F32S;
+ MOV64xw(x3, i64);
+ SDxw(x3, ed, fixedaddress);
+ SMWRITELOCK(lock);
+ }
+ break;
+
#define GO(Z) \
BARRIER(BARRIER_MAYBE); \
JUMP(addr+i8, 1); \
diff --git a/src/dynarec/rv64/dynarec_rv64_67_32.c b/src/dynarec/rv64/dynarec_rv64_67_32.c
new file mode 100644
index 0000000..aa663d3
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_67_32.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+
+#include "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_helper.h"
+#include "dynarec_rv64_functions.h"
+
+uintptr_t dynarec64_67_32(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+ (void)ip; (void)need_epilog;
+
+ uint8_t opcode = F8;
+ uint8_t nextop;
+ uint8_t gd, ed, wback, wb, wb1, wb2, gb1, gb2, eb1, eb2;
+ int64_t fixedaddress;
+ int unscaled;
+ int8_t i8;
+ uint8_t u8;
+ int32_t i32;
+ int64_t j64, i64;
+ int cacheupd = 0;
+ int lock;
+ int v0, v1, s0;
+
+ if(!rex.is32bits) {
+ // should do a different file
+ DEFAULT;
+ return addr;
+ }
+
+ rep = 0;
+ while((opcode==0xF2) || (opcode==0xF3)) {
+ rep = opcode-0xF1;
+ opcode = F8;
+ }
+
+ switch(opcode) {
+ default:
+ DEFAULT;
+ }
+ return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c
index 7f14468..885eebf 100644
--- a/src/dynarec/rv64/dynarec_rv64_d8.c
+++ b/src/dynarec/rv64/dynarec_rv64_d8.c
@@ -43,56 +43,45 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
switch(nextop) {
case 0xC0 ... 0xC7:
-
+ INST_NAME("FADD ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ if(ST_IS_F(0)) {
+ FADDS(v1, v1, v2);
+ } else {
+ FADDD(v1, v1, v2);
+ }
+ break;
case 0xC8 ... 0xCF:
-
+ INST_NAME("FMUL ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FMULS(v1, v1, v2);
+ } else {
+ FMULD(v1, v1, v2);
+ }
+ break;
case 0xD0 ... 0xD7:
-
+ INST_NAME("FCOM ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ break;
case 0xD8 ... 0xDF:
INST_NAME("FCOMP ST0, STx");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
- v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
- LHU(x3, xEmu, offsetof(x64emu_t, sw));
- MOV32w(x1, 0b1110100011111111); // mask off c0,c1,c2,c3
- AND(x3, x3, x1);
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
if(ST_IS_F(0)) {
- FEQS(x5, v1, v1);
- FEQS(x4, v2, v2);
- AND(x5, x5, x4);
- BEQZ(x5, 24); // undefined/NaN
- FEQS(x5, v1, v2);
- BNEZ(x5, 28); // equal
- FLTS(x3, v1, v2); // x3 = (v1<v2)?1:0
- SLLI(x1, x3, 8);
- J(20); // end
- // undefined/NaN
- LUI(x1, 1);
- ADDI(x1, x1, 0b010100000000);
- J(8); // end
- // equal
- LUI(x1, 1);
- // end
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
} else {
- FEQD(x5, v1, v1);
- FEQD(x4, v2, v2);
- AND(x5, x5, x4);
- BEQZ(x5, 24); // undefined/NaN
- FEQD(x5, v1, v2);
- BNEZ(x5, 28); // equal
- FLTD(x3, v1, v2); // x3 = (v1<v2)?1:0
- SLLI(x1, x3, 8);
- J(20); // end
- // undefined/NaN
- LUI(x1, 1);
- ADDI(x1, x1, 0b010100000000);
- J(8); // end
- // equal
- LUI(x1, 1);
- // end
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
}
- OR(x3, x3, x1);
- SH(x3, xEmu, offsetof(x64emu_t, sw));
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0 ... 0xE7:
INST_NAME("FSUB ST0, STx");
@@ -105,11 +94,19 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
break;
case 0xE8 ... 0xEF:
-
+ INST_NAME("FSUBR ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FSUBS(v1, v2, v1);
+ } else {
+ FSUBD(v1, v2, v1);
+ }
+ break;
case 0xF0 ... 0xF7:
INST_NAME("FDIV ST0, STx");
- v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
- v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
if(ST_IS_F(0)) {
FDIVS(v1, v1, v2);
} else {
@@ -117,7 +114,14 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
break;
case 0xF8 ... 0xFF:
- DEFAULT;
+ INST_NAME("FDIVR ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FDIVS(v1, v2, v1);
+ } else {
+ FDIVD(v1, v2, v1);
+ }
break;
default:
@@ -148,6 +152,33 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FMULD(v1, v1, s0);
}
break;
+ case 2:
+ INST_NAME("FCOM ST0, float[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+ s0 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLW(s0, ed, fixedaddress);
+ if (ST_IS_F(0)) {
+ FCOMS(v1, s0, x1, x6, x3, x4, x5);
+ } else {
+ FCVTDS(s0, s0);
+ FCOMD(v1, s0, x1, x6, x3, x4, x5);
+ }
+ break;
+ case 3:
+ INST_NAME("FCOMP ST0, float[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+ s0 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLW(s0, ed, fixedaddress);
+ if (ST_IS_F(0)) {
+ FCOMS(v1, s0, x1, x6, x3, x4, x5);
+ } else {
+ FCVTDS(s0, s0);
+ FCOMD(v1, s0, x1, x6, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
case 4:
INST_NAME("FSUB ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
@@ -161,6 +192,19 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FSUBD(v1, v1, s0);
}
break;
+ case 5:
+ INST_NAME("FSUBR ST0, float[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+ s0 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLW(s0, ed, fixedaddress);
+ if (ST_IS_F(0)) {
+ FSUBS(v1, s0, v1);
+ } else {
+ FCVTDS(s0, s0);
+ FSUBD(v1, s0, v1);
+ }
+ break;
case 6:
INST_NAME("FDIV ST0, float[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
@@ -174,8 +218,19 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FDIVD(v1, v1, s0);
}
break;
- default:
- DEFAULT;
+ case 7:
+ INST_NAME("FDIVR ST0, float[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+ s0 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLW(s0, ed, fixedaddress);
+ if (ST_IS_F(0)) {
+ FDIVS(v1, s0, v1);
+ } else {
+ FCVTDS(s0, s0);
+ FDIVD(v1, s0, v1);
+ }
+ break;
}
}
return addr;
diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c
index 4940d6b..d5f2ad6 100644
--- a/src/dynarec/rv64/dynarec_rv64_d9.c
+++ b/src/dynarec/rv64/dynarec_rv64_d9.c
@@ -54,7 +54,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xC6:
case 0xC7:
INST_NAME("FLD STx");
- v2 = x87_do_push(dyn, ninst, x1, X87_ST(nextop&7));
+ X87_PUSH_OR_FAIL(v2, dyn, ninst, x1, X87_ST(nextop&7));
v1 = x87_get_st(dyn, ninst, x1, x2, (nextop&7)+1, X87_COMBINE(0, (nextop&7)+1));
if(ST_IS_F(0)) {
FMVS(v2, v1);
@@ -87,7 +87,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xD8:
INST_NAME("FSTPNCE ST0, ST0");
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
case 0xDA:
@@ -101,7 +101,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
INST_NAME("FCHS");
@@ -135,7 +135,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xE8:
INST_NAME("FLD1");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F);
if(ST_IS_F(0)) {
MOV32w(x1, 0x3f800000);
FMVWX(v1, x1);
@@ -146,32 +146,32 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
break;
case 0xE9:
INST_NAME("FLDL2T");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FTABLE64(v1, L2T);
break;
- case 0xEA:
+ case 0xEA:
INST_NAME("FLDL2E");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FTABLE64(v1, L2E);
break;
case 0xEB:
INST_NAME("FLDPI");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FTABLE64(v1, PI);
break;
case 0xEC:
INST_NAME("FLDLG2");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FTABLE64(v1, LG2);
break;
case 0xED:
INST_NAME("FLDLN2");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FTABLE64(v1, LN2);
break;
case 0xEE:
INST_NAME("FLDZ");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F);
if(ST_IS_F(0)) {
FMVWX(v1, xZR);
} else {
@@ -191,14 +191,14 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fyl2x, -1);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF2:
INST_NAME("FPTAN");
MESSAGE(LOG_DUMP, "Need Optimization\n");
x87_forget(dyn, ninst, x1, x2, 0);
CALL(native_ftan, -1);
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F);
if(ST_IS_F(0)) {
MOV32w(x1, 0x3f800000);
FMVWX(v1, x1);
@@ -213,12 +213,12 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fpatan, -1);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF4:
INST_NAME("FXTRACT");
MESSAGE(LOG_DUMP, "Need Optimization\n");
- x87_do_push_empty(dyn, ninst, 0);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fxtract, -1);
break;
@@ -258,7 +258,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
x87_forget(dyn, ninst, x1, x2, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fyl2xp1, -1);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xFA:
INST_NAME("FSQRT");
@@ -272,7 +272,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xFB:
INST_NAME("FSINCOS");
MESSAGE(LOG_DUMP, "Need Optimization\n");
- x87_do_push_empty(dyn, ninst, 0);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0);
x87_forget(dyn, ninst, x1, x2, 1);
CALL(native_fsincos, -1);
break;
@@ -349,12 +349,12 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xEF:
DEFAULT;
break;
-
+
default:
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD ST0, float[ED]");
- v1 = x87_do_push(dyn, ninst, x1, box64_dynarec_x87double?EXT_CACHE_ST_D:EXT_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, box64_dynarec_x87double?EXT_CACHE_ST_D:EXT_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
FLW(v1, ed, fixedaddress);
if(!ST_IS_F(0)) {
@@ -381,7 +381,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FCVTSD(v1, v1);
}
FSW(v1, ed, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 4:
INST_NAME("FLDENV Ed");
diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c
new file mode 100644
index 0000000..6158409
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_da.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "emu/x87emu_private.h"
+#include "dynarec_native.h"
+
+#include "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_helper.h"
+#include "dynarec_rv64_functions.h"
+
+
+uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+ uint8_t nextop = F8;
+ int64_t j64;
+ uint8_t ed;
+ uint8_t wback;
+ int v1, v2;
+ int d0;
+ int s0;
+ int64_t fixedaddress;
+ int unscaled;
+
+ MAYUSE(s0);
+ MAYUSE(d0);
+ MAYUSE(v2);
+ MAYUSE(v1);
+ MAYUSE(ed);
+ MAYUSE(j64);
+
+ switch (nextop) {
+ case 0xC0:
+ case 0xC1:
+ case 0xC2:
+ case 0xC3:
+ case 0xC4:
+ case 0xC5:
+ case 0xC6:
+ case 0xC7:
+ INST_NAME("FCMOVB ST0, STx");
+ READFLAGS(X_CF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ ANDI(x1, xFlags, 1 << F_CF);
+ CBZ_NEXT(x1);
+ if (ST_IS_F(0))
+ FMVS(v1, v2);
+ else
+ FMVD(v1, v2);
+ break;
+ case 0xC8:
+ case 0xC9:
+ case 0xCA:
+ case 0xCB:
+ case 0xCC:
+ case 0xCD:
+ case 0xCE:
+ case 0xCF:
+ INST_NAME("FCMOVE ST0, STx");
+ READFLAGS(X_ZF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ ANDI(x1, xFlags, 1 << F_ZF);
+ CBZ_NEXT(x1);
+ if (ST_IS_F(0))
+ FMVS(v1, v2);
+ else
+ FMVD(v1, v2);
+ break;
+ case 0xD0:
+ case 0xD1:
+ case 0xD2:
+ case 0xD3:
+ case 0xD4:
+ case 0xD5:
+ case 0xD6:
+ case 0xD7:
+ INST_NAME("FCMOVBE ST0, STx");
+ READFLAGS(X_CF | X_ZF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF));
+ CBZ_NEXT(x1);
+ if (ST_IS_F(0))
+ FMVS(v1, v2);
+ else
+ FMVD(v1, v2);
+ break;
+ case 0xD8:
+ case 0xD9:
+ case 0xDA:
+ case 0xDB:
+ case 0xDC:
+ case 0xDD:
+ case 0xDE:
+ case 0xDF:
+ INST_NAME("FCMOVU ST0, STx");
+ READFLAGS(X_PF);
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ ANDI(x1, xFlags, (1 << F_PF));
+ CBZ_NEXT(x1);
+ if (ST_IS_F(0))
+ FMVS(v1, v2);
+ else
+ FMVD(v1, v2);
+ break;
+ case 0xE9:
+ INST_NAME("FUCOMPP ST0, ST1");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, 1, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
+ case 0xE4:
+ case 0xF0:
+ case 0xF1:
+ case 0xF4:
+ case 0xF5:
+ case 0xF6:
+ case 0xF7:
+ case 0xF8:
+ case 0xF9:
+ case 0xFD:
+ DEFAULT;
+ break;
+
+ default:
+ switch ((nextop >> 3) & 7) {
+ case 6:
+ INST_NAME("FIDIV ST0, Ed");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ LW(x1, ed, fixedaddress);
+ FCVTDW(v2, x1, RD_RNE);
+ FDIVD(v1, v1, v2);
+ break;
+ default:
+ DEFAULT;
+ break;
+ }
+ }
+ return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index 7a5dddb..f6c1f70 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -153,7 +153,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SET_DFNONE();
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
- IFX(F_ZF | F_PF | F_CF) {
+ IFX(X_ZF | X_PF | X_CF) {
if(ST_IS_F(0)) {
FEQS(x5, v1, v1);
FEQS(x4, v2, v2);
@@ -189,7 +189,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
}
break;
- case 0xF0:
+ case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
@@ -213,7 +213,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ed");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
LW(x1, ed, fixedaddress);
FCVTDW(v1, x1, RD_RNE); // i32 -> double
@@ -245,7 +245,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
MARK2;
SW(x4, wback, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 5:
INST_NAME("FLD tbyte");
@@ -268,13 +268,13 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SH(x6, ed, fixedaddress+8);
} else {
if(box64_x87_no80bits) {
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
FLD(v1, ed, fixedaddress);
} else {
if(ed!=x1) {
- MV(x1, ed);
+ ADDI(x1, ed, fixedaddress);
}
- x87_do_push_empty(dyn, ninst, x3);
+ X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3);
CALL(native_fld, -1);
}
}
@@ -293,7 +293,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
CALL(native_fstp, -1);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c
index d802e2f..dbf7b31 100644
--- a/src/dynarec/rv64/dynarec_rv64_dc.c
+++ b/src/dynarec/rv64/dynarec_rv64_dc.c
@@ -39,69 +39,135 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
switch(nextop) {
case 0xC0 ... 0xC7:
INST_NAME("FADD STx, ST0");
- DEFAULT;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FADDS(v1, v1, v2);
+ } else {
+ FADDD(v1, v1, v2);
+ }
break;
case 0xC8 ... 0xCF:
INST_NAME("FMUL STx, ST0");
- DEFAULT;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FMULS(v1, v1, v2);
+ } else {
+ FMULD(v1, v1, v2);
+ }
break;
case 0xD0 ... 0xD7:
INST_NAME("FCOM ST0, STx"); //yep
- DEFAULT;
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
break;
case 0xD8 ... 0xDF:
INST_NAME("FCOMP ST0, STx");
- DEFAULT;
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0 ... 0xE7:
INST_NAME("FSUBR STx, ST0");
- DEFAULT;
- break;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FSUBS(v1, v2, v1);
+ } else {
+ FSUBD(v1, v2, v1);
+ }
break;
case 0xE8 ... 0xEF:
INST_NAME("FSUB STx, ST0");
- DEFAULT;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FSUBS(v1, v1, v2);
+ } else {
+ FSUBD(v1, v1, v2);
+ }
break;
case 0xF0 ... 0xF7:
INST_NAME("FDIVR STx, ST0");
- DEFAULT;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FDIVS(v1, v2, v1);
+ } else {
+ FDIVD(v1, v2, v1);
+ }
break;
case 0xF8 ... 0xFF:
INST_NAME("FDIV STx, ST0");
- DEFAULT;
+ v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FDIVS(v1, v1, v2);
+ } else {
+ FDIVD(v1, v1, v2);
+ }
break;
default:
switch((nextop>>3)&7) {
+ case 0:
+ INST_NAME("FADD ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FADDD(v1, v1, v2);
+ break;
+ case 1:
+ INST_NAME("FMUL ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FMULD(v1, v1, v2);
+ break;
+ case 2:
+ INST_NAME("FCOM ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FCOMD(v1, v2, x1, x6, x3, x4, x5);
+ break;
case 3:
INST_NAME("FCOMP ST0, double[ED]");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
v2 = fpu_get_scratch(dyn);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
FLD(v2, wback, fixedaddress);
-
- LHU(x3, xEmu, offsetof(x64emu_t, sw));
- MOV32w(x1, 0b1110100011111111); // mask off c0,c1,c2,c3
- AND(x3, x3, x1);
- FEQD(x5, v1, v1);
- FEQD(x4, v2, v2);
- AND(x5, x5, x4);
- BEQZ(x5, 24); // undefined/NaN
- FEQD(x5, v1, v2);
- BNEZ(x5, 28); // equal
- FLTD(x3, v1, v2); // x3 = (v1<v2)?1:0
- SLLI(x1, x3, 8);
- J(20); // end
- // undefined/NaN
- LUI(x1, 1);
- ADDI(x1, x1, 0b010100000000);
- J(8); // end
- // equal
- LUI(x1, 1);
- // end
- OR(x3, x3, x1);
- SH(x3, xEmu, offsetof(x64emu_t, sw));
-
- x87_do_pop(dyn, ninst, x3);
+ FCOMD(v1, v2, x1, x6, x3, x4, x5);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
+ case 4:
+ INST_NAME("FSUB ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FSUBD(v1, v1, v2);
+ break;
+ case 5:
+ INST_NAME("FSUBR ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FSUBD(v1, v2, v1);
break;
case 6:
INST_NAME("FDIV ST0, double[ED]");
@@ -111,8 +177,14 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FLD(v2, wback, fixedaddress);
FDIVD(v1, v1, v2);
break;
- default:
- DEFAULT;
+ case 7:
+ INST_NAME("FDIVR ST0, double[ED]");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+ v2 = fpu_get_scratch(dyn);
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+ FLD(v2, wback, fixedaddress);
+ FDIVD(v1, v2, v1);
+ break;
}
}
return addr;
diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c
index 044f9aa..47718d6 100644
--- a/src/dynarec/rv64/dynarec_rv64_dd.c
+++ b/src/dynarec/rv64/dynarec_rv64_dd.c
@@ -64,11 +64,17 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xD6:
case 0xD7:
INST_NAME("FST ST0, STx");
- DEFAULT;
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FMVS(v2, v1);
+ } else {
+ FMVD(v2, v1);
+ }
break;
case 0xD8:
INST_NAME("FSTP ST0, ST0");
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
case 0xDA:
@@ -82,7 +88,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7));
x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
case 0xE1:
@@ -93,7 +99,13 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xE6:
case 0xE7:
INST_NAME("FUCOM ST0, STx");
- DEFAULT;
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
break;
case 0xE8:
case 0xE9:
@@ -104,7 +116,14 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xEE:
case 0xEF:
INST_NAME("FUCOMP ST0, STx");
- DEFAULT;
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
case 0xC9:
@@ -137,7 +156,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
switch((nextop>>3)&7) {
case 0:
INST_NAME("FLD double");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
FLD(v1, wback, fixedaddress);
break;
@@ -152,7 +171,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
FSD(v1, wback, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 7:
INST_NAME("FNSTSW m2byte");
diff --git a/src/dynarec/rv64/dynarec_rv64_de.c b/src/dynarec/rv64/dynarec_rv64_de.c
index a2341b4..f20cc68 100644
--- a/src/dynarec/rv64/dynarec_rv64_de.c
+++ b/src/dynarec/rv64/dynarec_rv64_de.c
@@ -52,7 +52,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FADDD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8:
case 0xC9:
@@ -70,7 +70,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FMULD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD0:
case 0xD1:
@@ -80,12 +80,27 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xD5:
case 0xD6:
case 0xD7:
- // INST_NAME("FCOMP ST0, STx"); //yep
- DEFAULT;
+ INST_NAME("FCOMP ST0, STx"); // yep
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD9:
- // INST_NAME("FCOMPP ST0, STx");
- DEFAULT;
+ INST_NAME("FCOMPP ST0, STx");
+ v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+ v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+ if (ST_IS_F(0)) {
+ FCOMS(v1, v2, x1, x2, x3, x4, x5);
+ } else {
+ FCOMD(v1, v2, x1, x2, x3, x4, x5);
+ }
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE0:
case 0xE1:
@@ -103,7 +118,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FSUBD(v1, v2, v1);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xE8:
case 0xE9:
@@ -121,7 +136,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FSUBD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xF0:
case 0xF1:
@@ -139,8 +154,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FDIVD(v1, v2, v1);
}
- x87_do_pop(dyn, ninst, x3);
- break;
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
case 0xF8:
case 0xF9:
case 0xFA:
@@ -157,7 +172,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
FDIVD(v1, v1, v2);
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xD8:
case 0xDA:
@@ -166,7 +181,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xDD:
case 0xDE:
case 0xDF:
- return 0;
+ DEFAULT;
+ break;
default:
switch((nextop>>3)&7) {
default:
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c
index de99b02..a2f6667 100644
--- a/src/dynarec/rv64/dynarec_rv64_df.c
+++ b/src/dynarec/rv64/dynarec_rv64_df.c
@@ -46,7 +46,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
case 0xE0:
INST_NAME("FNSTSW AX");
- LHU(x2, xEmu, offsetof(x64emu_t, top));
+ LWU(x2, xEmu, offsetof(x64emu_t, top));
LHU(x1, xEmu, offsetof(x64emu_t, sw));
MOV32w(x3, 0b1100011111111111); // mask
AND(x1, x1, x3);
@@ -68,7 +68,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7));
v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7));
CLEAR_FLAGS();
- IFX(F_ZF | F_PF | F_CF) {
+ IFX(X_ZF | X_PF | X_CF) {
if(ST_IS_F(0)) {
FEQS(x5, v1, v1);
FEQS(x4, v2, v2);
@@ -103,7 +103,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
// end
}
}
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 0xC8 ... 0xDF:
case 0xE1 ... 0xE7:
@@ -115,7 +115,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
switch((nextop>>3)&7) {
case 0:
INST_NAME("FILD ST0, Ew");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F);
addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0);
LH(x1, wback, fixedaddress);
if(ST_IS_F(0)) {
@@ -144,7 +144,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
MARK2;
SH(x4, wback, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 3:
INST_NAME("FISTP Ew, ST0");
@@ -168,11 +168,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
MARK2;
SH(x4, wback, fixedaddress);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
case 5:
INST_NAME("FILD ST0, i64");
- v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
+ X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
LD(x1, wback, fixedaddress);
if (rex.is32bits) {
@@ -193,6 +193,14 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
FSD(v1, x5, 0); // ref
}
break;
+ case 6:
+ INST_NAME("FBSTP tbytes, ST0");
+ x87_forget(dyn, ninst, x1, x2, 0);
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+ if (ed != x1) { MV(x1, ed); }
+ CALL(fpu_fbst, -1);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
+ break;
case 7:
INST_NAME("FISTP i64, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
@@ -233,7 +241,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
SD(x4, wback, fixedaddress);
MARK3;
x87_restoreround(dyn, ninst, u8);
- x87_do_pop(dyn, ninst, x3);
+ X87_POP_OR_FAIL(dyn, ninst, x3);
break;
default:
DEFAULT;
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_math.c b/src/dynarec/rv64/dynarec_rv64_emit_math.c
index 5d6f7e0..3664a8d 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_math.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c
@@ -63,7 +63,7 @@ void emit_add32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s5, s1); // s5 = ~res
AND(s3, s5, s3); // s3 = ~res & (op1 | op2)
@@ -160,7 +160,7 @@ void emit_add32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s3); // s3 = ~res & (op1 | op2)
@@ -218,7 +218,7 @@ void emit_add16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s5, s1); // s5 = ~res
AND(s3, s5, s3); // s3 = ~res & (op1 | op2)
@@ -280,7 +280,7 @@ void emit_add8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4)
IFX(X_AF|X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s4, s1); // s4 = ~res
AND(s3, s4, s3); // s3 = ~res & (op1 | op2)
@@ -336,7 +336,7 @@ void emit_add8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s2, int s3, i
SET_DFNONE();
}
IFX(X_AF | X_OF) {
- if(X_PEND) {} else {MOV32w(s4, c&0xff);}
+ IFX(X_PEND) {} else {MOV32w(s4, c&0xff);}
OR(s3, s1, s4); // s3 = op1 | op2
AND(s4, s1, s4); // s4 = op1 & op2
}
@@ -344,7 +344,7 @@ void emit_add8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s2, int s3, i
IFX(X_AF|X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s3); // s3 = ~res & (op1 | op2)
@@ -596,7 +596,7 @@ void emit_inc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s3); // s3 = ~res & (op1 | op2)
@@ -709,7 +709,7 @@ void emit_inc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s3); // s3 = ~res & (op1 | op2)
@@ -825,7 +825,7 @@ void emit_inc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4)
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s3); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s3); // s3 = ~res & (op1 | op2)
@@ -968,8 +968,8 @@ void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
SET_DFNONE();
}
IFX(X_AF | X_OF) {
- OR(s4, s1, s2); // s3 = op1 | op2
- AND(s5, s1, s2); // s4 = op1 & op2
+ OR(s4, s1, s2); // s4 = op1 | op2
+ AND(s5, s1, s2); // s5 = op1 & op2
}
ADD(s1, s1, s2);
@@ -982,7 +982,7 @@ void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s4); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s4, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s4); // s3 = ~res & (op1 | op2)
@@ -1304,8 +1304,8 @@ void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
SET_DFNONE();
}
IFX(X_AF | X_OF) {
- OR(s4, s1, s2); // s3 = op1 | op2
- AND(s5, s1, s2); // s4 = op1 & op2
+ OR(s4, s1, s2); // s4 = op1 | op2
+ AND(s5, s1, s2); // s5 = op1 & op2
}
ADD(s1, s1, s2);
@@ -1318,7 +1318,7 @@ void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4,
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s4); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s4, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s4); // s3 = ~res & (op1 | op2)
@@ -1386,8 +1386,8 @@ void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
}
}
IFX(X_AF | X_OF) {
- OR(s4, s1, s2); // s3 = op1 | op2
- AND(s5, s1, s2); // s4 = op1 & op2
+ OR(s4, s1, s2); // s4 = op1 | op2
+ AND(s5, s1, s2); // s5 = op1 & op2
}
ADDxw(s1, s1, s2);
@@ -1404,7 +1404,7 @@ void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
}
IFX(X_AF | X_OF) {
if(rv64_zbb) {
- ANDN(s3, s1, s4); // s3 = ~res & (op1 | op2)
+ ANDN(s3, s4, s1); // s3 = ~res & (op1 | op2)
} else {
NOT(s2, s1); // s2 = ~res
AND(s3, s2, s4); // s3 = ~res & (op1 | op2)
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
index 7030c67..2460bd7 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c
@@ -385,8 +385,8 @@ void emit_ror32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
SDxw(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
- SRLI(s3, s1, rex.w?63:31);
- AND(xFlags, xFlags, s3);
+ SRLIxw(s3, s1, rex.w?63:31);
+ OR(xFlags, xFlags, s3);
}
IFX(X_OF) {
ADDI(s3, xZR, 1);
@@ -421,6 +421,8 @@ void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
}
if(rv64_zbb) {
RORIxw(s1, s1, (rex.w?64:32)-c);
+ } else if (rv64_xtheadbb) {
+ TH_SRRIxw(s1, s1, (rex.w?64:32)-c);
} else {
SLLIxw(s3, s1, c);
SRLIxw(s1, s1, (rex.w?64:32)-c);
@@ -466,6 +468,8 @@ void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
}
if(rv64_zbb) {
RORIxw(s1, s1, c);
+ } else if (rv64_xtheadbb) {
+ TH_SRRIxw(s1, s1, c);
} else {
SRLIxw(s3, s1, c);
SLLIxw(s1, s1, (rex.w?64:32)-c);
@@ -475,8 +479,8 @@ void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c,
SDxw(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
- SRLI(s3, s1, rex.w?63:31);
- AND(xFlags, xFlags, s3);
+ SRLIxw(s3, s1, rex.w?63:31);
+ OR(xFlags, xFlags, s3);
}
IFX(X_OF) {
if(c==1) {
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index bb5c78c..d90aa34 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -49,8 +49,9 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
GETREX();
- // TODO: Take care of unligned memory access for all the LOCK ones.
- // https://github.com/ptitSeb/box64/pull/604
+ // TODO: Add support for unligned memory access for all the LOCK ones.
+ // TODO: Add support for BOX4_DYNAREC_ALIGNED_ATOMICS.
+
switch(opcode) {
case 0x01:
INST_NAME("LOCK ADD Ed, Gd");
@@ -214,13 +215,29 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
} else {
SMDMB();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+ ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+ BNEZ_MARK3(x1);
+ // Aligned
MARKLOCK;
LRxw(x1, wback, 1, 1);
SUBxw(x3, x1, xRAX);
- BNE_MARK(x3, xZR);
+ BNEZ_MARK(x3);
// EAX == Ed
SCxw(x4, gd, wback, 1, 1);
BNEZ_MARKLOCK(x4);
+ B_MARK_nocond;
+ MARK3;
+ // Unaligned
+ ANDI(x5, wback, -(1 << (rex.w + 2)));
+ MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks.
+ LDxw(x6, wback, 0);
+ LRxw(x1, x5, 1, 1);
+ SUBxw(x3, x6, xRAX);
+ BNEZ_MARK(x3);
+ // EAX == Ed
+ SCxw(x4, x1, x5, 1, 1);
+ BNEZ_MARK2(x4);
+ SDxw(gd, wback, 0);
MARK;
UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6);}
MVxw(xRAX, x1);
@@ -371,7 +388,7 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
MARKLOCK;
LR_W(x5, wback, 1, 1);
ANDI(x4, x5, 0xff); // x4 = Ed.b[0]
- ANDI(x5, x5, -256); // x5 = clear Ed.b[0]
+ ANDI(x5, x5, ~0xff); // x5 = clear Ed.b[0]
ADDW(x6, x4, x2);
ANDI(x9, xFlags, 1 << F_CF);
ADDW(x6, x6, x9); // x6 = adc
@@ -533,20 +550,40 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6);
} else {
+ SMDMB();
addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
if(opcode==0x81) i64 = F32S; else i64 = F8S;
+ if (i64 < -2048 || i64 >= 2048)
+ MOV64xw(x4, i64);
+ ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+ BNEZ_MARK3(x1);
+ // Aligned
MARKLOCK;
LRxw(x1, wback, 1, 1);
- if(i64>=-2048 && i64<2048)
+ if (i64 >= -2048 && i64 < 2048)
ADDIxw(x4, x1, i64);
- else {
- MOV64xw(x4, i64);
+ else
ADDxw(x4, x1, x4);
- }
SCxw(x3, x4, wback, 1, 1);
BNEZ_MARKLOCK(x3);
- IFX(X_ALL|X_PEND)
+ B_MARK_nocond;
+ MARK3;
+ // Unaligned
+ ANDI(x5, wback, -(1 << (rex.w + 2)));
+ MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks.
+ LDxw(x6, wback, 0);
+ LRxw(x1, x5, 1, 1);
+ if (i64 >= -2048 && i64 < 2048)
+ ADDIxw(x4, x6, i64);
+ else
+ ADDxw(x4, x6, x4);
+ SCxw(x3, x1, x5, 1, 1);
+ BNEZ_MARK2(x3);
+ SDxw(x4, wback, 0);
+ MARK;
+ IFX (X_ALL | X_PEND)
emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
+ SMDMB();
}
break;
case 1: // OR
@@ -640,6 +677,41 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
}
SMDMB();
break;
+ case 0x87:
+ INST_NAME("LOCK XCHG Ed, Gd");
+ nextop = F8;
+ if (MODREG) {
+ GETGD;
+ GETED(0);
+ MV(x1, gd);
+ MV(gd, ed);
+ MV(ed, x1);
+ } else {
+ SMDMB();
+ GETGD;
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+ ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+ BNEZ_MARK3(x1);
+ // Aligned
+ MARKLOCK;
+ LRxw(x1, wback, 1, 1);
+ SCxw(x4, gd, wback, 1, 1);
+ BNEZ_MARKLOCK(x4);
+ B_MARK_nocond;
+ MARK3;
+ // Unaligned
+ ANDI(x5, wback, -(1 << (rex.w + 2)));
+ MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks.
+ LDxw(x1, wback, 0);
+ LRxw(x3, x5, 1, 1);
+ SCxw(x4, x3, x5, 1, 1);
+ BNEZ_MARK2(x4);
+ SDxw(gd, wback, 0);
+ MARK;
+ MVxw(gd, x1);
+ SMDMB();
+ }
+ break;
case 0xFF:
nextop = F8;
switch((nextop>>3)&7)
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index ac3da81..62b6654 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -146,33 +146,6 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
opcode = F8;
switch(opcode) {
- case 0xF0:
- INST_NAME("(unsupported) CRC32 Gd, Eb)");
- nextop = F8;
- addr = fakeed(dyn, addr, ninst, nextop);
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
- GETIP(ip);
- STORE_XEMU_CALL();
- CALL(native_ud, -1);
- LOAD_XEMU_CALL();
- jump_to_epilog(dyn, 0, xRIP, ninst);
- *need_epilog = 0;
- *ok = 0;
- break;
- case 0xF1:
- INST_NAME("(unsupported) CRC32 Gd, Ed)");
- nextop = F8;
- addr = fakeed(dyn, addr, ninst, nextop);
- SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
- GETIP(ip);
- STORE_XEMU_CALL();
- CALL(native_ud, -1);
- LOAD_XEMU_CALL();
- jump_to_epilog(dyn, 0, xRIP, ninst);
- *need_epilog = 0;
- *ok = 0;
- break;
-
default:
DEFAULT;
}
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index 0c0676e..1b57e9e 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -24,7 +24,8 @@
uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
{
- (void)ip; (void)need_epilog;
+ (void)ip;
+ (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop, u8;
@@ -46,14 +47,14 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
MAYUSE(v1);
MAYUSE(j64);
- switch(opcode) {
+ switch (opcode) {
case 0x10:
INST_NAME("MOVSS Gx, Ex");
nextop = F8;
GETG;
- if(MODREG) {
+ if (MODREG) {
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
- q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 1);
+ q0 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 1);
FMVS(v0, q0);
} else {
v0 = sse_get_reg_empty(dyn, ninst, x1, gd, 1);
@@ -61,8 +62,8 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 8, 0);
FLW(v0, ed, fixedaddress);
// reset upper part
- SW(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+4);
- SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+8);
+ SW(xZR, xEmu, offsetof(x64emu_t, xmm[gd]) + 4);
+ SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd]) + 8);
}
break;
case 0x11:
@@ -70,8 +71,8 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETG;
v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
- if(MODREG) {
- q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 1);
+ if (MODREG) {
+ q0 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 1);
FMVS(q0, v0);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
@@ -88,12 +89,12 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
// GX->ud[1] = GX->ud[0] = EX->ud[0];
// GX->ud[3] = GX->ud[2] = EX->ud[2];
- LD(x3, wback, fixedaddress+0);
- SD(x3, gback, gdoffset+0);
- SD(x3, gback, gdoffset+4);
- LD(x3, wback, fixedaddress+8);
- SD(x3, gback, gdoffset+8);
- SD(x3, gback, gdoffset+12);
+ LD(x3, wback, fixedaddress + 0);
+ SD(x3, gback, gdoffset + 0);
+ SD(x3, gback, gdoffset + 4);
+ LD(x3, wback, fixedaddress + 8);
+ SD(x3, gback, gdoffset + 8);
+ SD(x3, gback, gdoffset + 12);
break;
case 0x1E:
INST_NAME("NOP / ENDBR32 / ENDBR64");
@@ -106,7 +107,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGXSS(v0);
GETED(0);
- if(rex.w) {
+ if (rex.w) {
FCVTSL(v0, ed, RD_RNE);
} else {
FCVTSW(v0, ed, RD_RNE);
@@ -118,17 +119,17 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGD;
GETEXSS(d0, 0);
- if(!box64_dynarec_fastround) {
- FSFLAGSI(0); // // reset all bits
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
}
FCVTSxw(gd, d0, RD_RTZ);
- if(!rex.w)
+ if (!rex.w)
ZEROUP(gd);
- if(!box64_dynarec_fastround) {
- FRFLAGS(x5); // get back FPSR to check the IOC bit
- ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF));
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
CBZ_NEXT(x5);
- if(rex.w) {
+ if (rex.w) {
MOV64x(gd, 0x8000000000000000LL);
} else {
MOV32w(gd, 0x80000000);
@@ -140,19 +141,19 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETGD;
GETEXSS(d0, 0);
- if(!box64_dynarec_fastround) {
- FSFLAGSI(0); // // reset all bits
+ if (!box64_dynarec_fastround) {
+ FSFLAGSI(0); // // reset all bits
}
u8 = sse_setround(dyn, ninst, x5, x6);
FCVTSxw(gd, d0, RD_DYN);
x87_restoreround(dyn, ninst, u8);
- if(!rex.w)
+ if (!rex.w)
ZEROUP(gd);
- if(!box64_dynarec_fastround) {
- FRFLAGS(x5); // get back FPSR to check the IOC bit
- ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF));
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
CBZ_NEXT(x5);
- if(rex.w) {
+ if (rex.w) {
MOV64x(gd, 0x8000000000000000LL);
} else {
MOV32w(gd, 0x80000000);
@@ -257,31 +258,31 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
u8 = F8;
int32_t idx;
- idx = 4+((u8>>(0*2))&3);
- LHU(x3, wback, fixedaddress+idx*2);
- idx = 4+((u8>>(1*2))&3);
- LHU(x4, wback, fixedaddress+idx*2);
- idx = 4+((u8>>(2*2))&3);
- LHU(x5, wback, fixedaddress+idx*2);
- idx = 4+((u8>>(3*2))&3);
- LHU(x6, wback, fixedaddress+idx*2);
+ idx = 4 + ((u8 >> (0 * 2)) & 3);
+ LHU(x3, wback, fixedaddress + idx * 2);
+ idx = 4 + ((u8 >> (1 * 2)) & 3);
+ LHU(x4, wback, fixedaddress + idx * 2);
+ idx = 4 + ((u8 >> (2 * 2)) & 3);
+ LHU(x5, wback, fixedaddress + idx * 2);
+ idx = 4 + ((u8 >> (3 * 2)) & 3);
+ LHU(x6, wback, fixedaddress + idx * 2);
- SH(x3, gback, gdoffset+(4+0)*2);
- SH(x4, gback, gdoffset+(4+1)*2);
- SH(x5, gback, gdoffset+(4+2)*2);
- SH(x6, gback, gdoffset+(4+3)*2);
+ SH(x3, gback, gdoffset + (4 + 0) * 2);
+ SH(x4, gback, gdoffset + (4 + 1) * 2);
+ SH(x5, gback, gdoffset + (4 + 2) * 2);
+ SH(x6, gback, gdoffset + (4 + 3) * 2);
- if (!(MODREG && (gd==ed))) {
- LD(x3, wback, fixedaddress+0);
- SD(x3, gback, gdoffset+0);
+ if (!(MODREG && (gd == ed))) {
+ LD(x3, wback, fixedaddress + 0);
+ SD(x3, gback, gdoffset + 0);
}
break;
case 0x7E:
INST_NAME("MOVQ Gx, Ex");
nextop = F8;
// Will load Gx as SD. Is that a good choice?
- if(MODREG) {
- v1 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 0);
+ if (MODREG) {
+ v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
GETGXSD_empty(v0);
FMVD(v0, v1);
} else {
@@ -290,7 +291,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
FLD(v0, ed, fixedaddress);
}
- SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+8);
+ SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd]) + 8);
break;
case 0x7F:
INST_NAME("MOVDQU Ex,Gx");
@@ -298,7 +299,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
SSE_LOOP_MV_Q2(x3);
- if(!MODREG) SMWRITE2();
+ if (!MODREG) SMWRITE2();
break;
case 0x5B:
@@ -307,19 +308,19 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGX();
GETEX(x2, 0);
v0 = fpu_get_scratch(dyn);
- for(int i=0; i<4; ++i) {
- if(!box64_dynarec_fastround) {
+ for (int i = 0; i < 4; ++i) {
+ if (!box64_dynarec_fastround) {
FSFLAGSI(0); // reset all bits
}
- FLW(v0, wback, fixedaddress+i*4);
+ FLW(v0, wback, fixedaddress + i * 4);
FCVTWS(x3, v0, RD_RTZ);
- if(!box64_dynarec_fastround) {
- FRFLAGS(x5); // get back FPSR to check the IOC bit
- ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF));
+ if (!box64_dynarec_fastround) {
+ FRFLAGS(x5); // get back FPSR to check the IOC bit
+ ANDI(x5, x5, (1 << FR_NV) | (1 << FR_OF));
BEQZ(x5, 8);
MOV32w(x3, 0x80000000);
}
- SW(x3, gback, gdoffset+i*4);
+ SW(x3, gback, gdoffset + i * 4);
}
break;
case 0xB8:
@@ -329,17 +330,17 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETED(0);
GETGD;
- if(!rex.w && MODREG) {
+ if (!rex.w && MODREG) {
AND(x4, ed, xMASK);
ed = x4;
}
CLEAR_FLAGS();
BNE_MARK(ed, xZR);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ORI(xFlags, xFlags, 1 << F_ZF);
MOV32w(gd, 0);
B_NEXT_nocond;
MARK;
- if(rv64_zbb) {
+ if (rv64_zbb) {
CPOPxw(gd, ed);
} else {
TABLE64(x1, 0x5555555555555555uLL);
@@ -371,75 +372,75 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
nextop = F8;
GETED(0);
GETGD;
- if(!rex.w && MODREG) {
+ if (!rex.w && MODREG) {
AND(x4, ed, xMASK);
ed = x4;
}
- ANDI(xFlags, xFlags, ~((1<<F_ZF) | (1<<F_CF)));
+ ANDI(xFlags, xFlags, ~((1 << F_ZF) | (1 << F_CF)));
BNE_MARK(ed, xZR);
- ORI(xFlags, xFlags, 1<<F_CF);
- MOV32w(gd, rex.w?64:32);
+ ORI(xFlags, xFlags, 1 << F_CF);
+ MOV32w(gd, rex.w ? 64 : 32);
B_NEXT_nocond;
MARK;
- if(rv64_zbb) {
+ if (rv64_zbb) {
CTZxw(gd, ed);
} else {
NEG(x2, ed);
AND(x2, x2, ed);
TABLE64(x3, 0x03f79d71b4ca8b09ULL);
MUL(x2, x2, x3);
- SRLI(x2, x2, 64-6);
+ SRLI(x2, x2, 64 - 6);
TABLE64(x1, (uintptr_t)&deBruijn64tab);
ADD(x1, x1, x2);
LBU(gd, x1, 0);
}
- BNE(gd, xZR, 4+4);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ BNE(gd, xZR, 4 + 4);
+ ORI(xFlags, xFlags, 1 << F_ZF);
break;
case 0xBD:
INST_NAME("LZCNT Gd, Ed");
- SETFLAGS(X_ZF|X_CF, SF_SUBSET);
+ SETFLAGS(X_ZF | X_CF, SF_SUBSET);
SET_DFNONE();
nextop = F8;
GETED(0);
GETGD;
- if(!rex.w && MODREG) {
+ if (!rex.w && MODREG) {
AND(x4, ed, xMASK);
ed = x4;
}
BNE_MARK(ed, xZR);
- MOV32w(gd, rex.w?64:32);
- ANDI(xFlags, xFlags, ~(1<<F_ZF));
- ORI(xFlags, xFlags, 1<<F_CF);
+ MOV32w(gd, rex.w ? 64 : 32);
+ ANDI(xFlags, xFlags, ~(1 << F_ZF));
+ ORI(xFlags, xFlags, 1 << F_CF);
B_NEXT_nocond;
MARK;
- if(rv64_zbb) {
+ if (rv64_zbb) {
CLZxw(gd, ed);
} else {
- if(ed!=gd)
+ if (ed != gd)
u8 = gd;
else
u8 = x1;
- ADDI(u8, xZR, rex.w?63:31);
- if(rex.w) {
+ ADDI(u8, xZR, rex.w ? 63 : 31);
+ if (rex.w) {
MV(x2, ed);
SRLI(x3, x2, 32);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
SUBI(u8, u8, 32);
MV(x2, x3);
} else {
AND(x2, ed, xMASK);
}
SRLI(x3, x2, 16);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
SUBI(u8, u8, 16);
MV(x2, x3);
SRLI(x3, x2, 8);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
SUBI(u8, u8, 8);
MV(x2, x3);
SRLI(x3, x2, 4);
- BEQZ(x3, 4+2*4);
+ BEQZ(x3, 4 + 2 * 4);
SUBI(u8, u8, 4);
MV(x2, x3);
ANDI(x2, x2, 0b1111);
@@ -449,9 +450,9 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
SUB(gd, u8, x2);
MARK2;
}
- ANDI(xFlags, xFlags, ~((1<<F_ZF) | (1<<F_CF)));
- BNE(gd, xZR, 4+4);
- ORI(xFlags, xFlags, 1<<F_ZF);
+ ANDI(xFlags, xFlags, ~((1 << F_ZF) | (1 << F_CF)));
+ BNE(gd, xZR, 4 + 4);
+ ORI(xFlags, xFlags, 1 << F_ZF);
break;
case 0xC2:
@@ -460,9 +461,9 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETGXSS(d0);
GETEXSS(d1, 1);
u8 = F8;
- if ((u8&7) == 0) { // Equal
+ if ((u8 & 7) == 0) { // Equal
FEQS(x2, d0, d1);
- } else if ((u8&7) == 4) { // Not Equal or unordered
+ } else if ((u8 & 7) == 4) { // Not Equal or unordered
FEQS(x2, d0, d1);
XORI(x2, x2, 1);
} else {
@@ -471,27 +472,33 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
FEQS(x2, d1, d1);
AND(x2, x2, x3);
- switch(u8&7) {
- case 1: BEQ_MARK(x2, xZR); FLTS(x2, d0, d1); break; // Less than
- case 2: BEQ_MARK(x2, xZR); FLES(x2, d0, d1); break; // Less or equal
- case 3: XORI(x2, x2, 1); break; // NaN
- case 5: { // Greater or equal or unordered
- BEQ_MARK2(x2, xZR);
- FLES(x2, d1, d0);
- B_MARK_nocond;
- break;
- }
- case 6: { // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
- BEQ_MARK2(x2, xZR);
- FLTS(x2, d1, d0);
- B_MARK_nocond;
- break;
- }
- case 7: break; // Not NaN
+ switch (u8 & 7) {
+ case 1:
+ BEQ_MARK(x2, xZR);
+ FLTS(x2, d0, d1);
+ break; // Less than
+ case 2:
+ BEQ_MARK(x2, xZR);
+ FLES(x2, d0, d1);
+ break; // Less or equal
+ case 3: XORI(x2, x2, 1); break; // NaN
+ case 5: { // Greater or equal or unordered
+ BEQ_MARK2(x2, xZR);
+ FLES(x2, d1, d0);
+ B_MARK_nocond;
+ break;
+ }
+ case 6: { // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
+ BEQ_MARK2(x2, xZR);
+ FLTS(x2, d1, d0);
+ B_MARK_nocond;
+ break;
+ }
+ case 7: break; // Not NaN
}
MARK2;
- if ((u8&7) == 5 || (u8&7) == 6) {
+ if ((u8 & 7) == 5 || (u8 & 7) == 6) {
MOV32w(x2, 1);
}
MARK;
@@ -507,12 +514,12 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
GETEX(x2, 0);
q0 = fpu_get_scratch(dyn);
q1 = fpu_get_scratch(dyn);
- LW(x3, wback, fixedaddress+0);
- LW(x4, wback, fixedaddress+4);
+ LW(x3, wback, fixedaddress + 0);
+ LW(x4, wback, fixedaddress + 4);
FCVTDW(q0, x3, RD_RTZ);
FCVTDW(q1, x4, RD_RTZ);
- FSD(q0, gback, gdoffset+0);
- FSD(q1, gback, gdoffset+8);
+ FSD(q0, gback, gdoffset + 0);
+ FSD(q1, gback, gdoffset + 8);
break;
default:
diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c
index 541ac45..f01c638 100644
--- a/src/dynarec/rv64/dynarec_rv64_functions.c
+++ b/src/dynarec/rv64/dynarec_rv64_functions.c
@@ -58,7 +58,7 @@ void fpu_free_reg(dynarec_rv64_t* dyn, int reg)
int idx = EXTIDX(reg);
// TODO: check upper limit?
dyn->e.fpuused[idx] = 0;
- if(dyn->e.extcache[reg].t!=EXT_CACHE_ST_F && dyn->e.extcache[reg].t!=EXT_CACHE_ST_D)
+ if(dyn->e.extcache[idx].t!=EXT_CACHE_ST_F && dyn->e.extcache[idx].t!=EXT_CACHE_ST_D)
dyn->e.extcache[idx].v = 0;
}
// Get an MMX double reg
@@ -494,7 +494,7 @@ const char* getCacheName(int t, int n)
void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
{
static const char* fnames[] = {
- "ft0"," ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
+ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
"fs0", "fs1",
"fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7",
"fs2", "fs3", "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "fs10", "fs11",
@@ -561,4 +561,4 @@ void print_newinst(dynarec_native_t* dyn, int ninst)
ninst, dyn->block, dyn->native_size,
(box64_dynarec_dump>1)?"\e[m":""
);
-} \ No newline at end of file
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index a005c3b..8fe096b 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -56,16 +56,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
if (sib_reg!=4) {
if(tmp && ((tmp<-2048) || (tmp>maxval) || !i12)) {
MOV64x(scratch, tmp);
- if((sib>>6)) {
- if(rv64_zba) {
- SHxADD(ret, xRAX+sib_reg, sib>>6, scratch);
- } else {
- SLLI(ret, xRAX+sib_reg, (sib>>6));
- ADD(ret, ret, scratch);
- }
- } else {
- ADD(ret, xRAX+sib_reg, scratch);
- }
+ ADDSL(ret, scratch, xRAX+sib_reg, sib>>6, ret);
} else {
if(sib>>6) {
SLLI(ret, xRAX+sib_reg, (sib>>6));
@@ -82,16 +73,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
}
} else {
if (sib_reg!=4) {
- if(sib>>6) {
- if(rv64_zba) {
- SHxADD(ret, xRAX+sib_reg, sib>>6, xRAX+sib_reg2);
- } else {
- SLLI(scratch, xRAX+sib_reg, (sib>>6));
- ADD(ret, xRAX+sib_reg2, scratch);
- }
- } else {
- ADD(ret, xRAX+sib_reg2, xRAX+sib_reg);
- }
+ ADDSL(ret, xRAX+sib_reg2, xRAX+sib_reg, sib>>6, scratch);
} else {
ret = xRAX+sib_reg2;
}
@@ -146,16 +128,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
*fixaddress = i64;
if((nextop&7)==4) {
if (sib_reg!=4) {
- if(sib>>6) {
- if(rv64_zba) {
- SHxADD(ret, xRAX+sib_reg, sib>>6, xRAX+sib_reg2);
- } else {
- SLLI(scratch, xRAX+sib_reg, (sib>>6));
- ADD(ret, xRAX+sib_reg2, scratch);
- }
- } else {
- ADD(ret, xRAX+sib_reg2, xRAX+sib_reg);
- }
+ ADDSL(ret, xRAX+sib_reg2, xRAX+sib_reg, sib>>6, scratch);
} else {
ret = xRAX+sib_reg2;
}
@@ -165,16 +138,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
if(i64>=-2048 && i64<=2047) {
if((nextop&7)==4) {
if (sib_reg!=4) {
- if(sib>>6) {
- if(rv64_zba) {
- SHxADD(scratch, xRAX+sib_reg, sib>>6, xRAX+sib_reg2);
- } else {
- SLLI(scratch, xRAX+sib_reg, (sib>>6));
- ADD(scratch, xRAX+sib_reg2, scratch);
- }
- } else {
- ADD(scratch, xRAX+sib_reg2, xRAX+sib_reg);
- }
+ ADDSL(scratch, xRAX+sib_reg2, xRAX+sib_reg, sib>>6, scratch);
} else {
scratch = xRAX+sib_reg2;
}
@@ -186,16 +150,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
if((nextop&7)==4) {
if (sib_reg!=4) {
ADD(scratch, scratch, xRAX+sib_reg2);
- if(sib>>6) {
- if(rv64_zba) {
- SHxADD(ret, xRAX+sib_reg, sib>>6, scratch);
- } else {
- SLLI(ret, xRAX+sib_reg, (sib>>6));
- ADD(ret, scratch, ret);
- }
- } else {
- ADD(ret, scratch, xRAX+sib_reg);
- }
+ ADDSL(ret, scratch, xRAX+sib_reg, sib>>6, ret);
} else {
PASS3(int tmp = xRAX+sib_reg2);
ADD(ret, tmp, scratch);
@@ -507,7 +462,9 @@ void jump_to_epilog_fast(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
SMEND();
BR(x2);
}
-
+#ifdef JMPTABLE_SHIFT4
+#error TODO!
+#endif
void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
{
MAYUSE(dyn); MAYUSE(ninst);
@@ -1718,9 +1675,9 @@ static void swapCache(dynarec_rv64_t* dyn, int ninst, int i, int j, extcache_t *
// SWAP
ext_cache_t tmp;
MESSAGE(LOG_DUMP, "\t - Swapping %d <-> %d\n", i, j);
- // There is no VSWP in Arm64 NEON to swap 2 register contents!
+ // There is no swap instruction in RV64 to swap 2 float registers!
// so use a scratch...
- #define SCRATCH 0
+ #define SCRATCH 2
if(i_single)
FMVS(SCRATCH, reg_i);
else
@@ -1770,7 +1727,7 @@ static void loadCache(dynarec_rv64_t* dyn, int ninst, int stack_cnt, int s1, int
break;
case EXT_CACHE_MM:
MESSAGE(LOG_DUMP, "\t - Loading %s\n", getCacheName(t, n));
- FLD(reg, xEmu, offsetof(x64emu_t, mmx[i]));
+ FLD(reg, xEmu, offsetof(x64emu_t, mmx[n]));
break;
case EXT_CACHE_ST_D:
case EXT_CACHE_ST_F:
@@ -1926,7 +1883,9 @@ static void fpuCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1, int s2, in
s3_top = 0;
stack_cnt = cache_i2.stack;
}
- extcache_t cache = dyn->e;
+
+ // FIXME: why we can't just use dyn->e here? debug that!
+ extcache_t cache = dyn->insts[ninst].e;
int s1_val = 0;
int s2_val = 0;
// unload every uneeded cache
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 0b1023b..140d90c 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -20,35 +20,38 @@
#define F8 *(uint8_t*)(addr++)
#define F8S *(int8_t*)(addr++)
-#define F16 *(uint16_t*)(addr+=2, addr-2)
-#define F16S *(int16_t*)(addr+=2, addr-2)
-#define F32 *(uint32_t*)(addr+=4, addr-4)
-#define F32S *(int32_t*)(addr+=4, addr-4)
-#define F32S64 (uint64_t)(int64_t)F32S
-#define F64 *(uint64_t*)(addr+=8, addr-8)
-#define PK(a) *(uint8_t*)(addr+a)
-#define PK16(a) *(uint16_t*)(addr+a)
-#define PK32(a) *(uint32_t*)(addr+a)
-#define PK64(a) *(uint64_t*)(addr+a)
-#define PKip(a) *(uint8_t*)(ip+a)
+#define F16 *(uint16_t*)(addr += 2, addr - 2)
+#define F16S *(int16_t*)(addr += 2, addr - 2)
+#define F32 *(uint32_t*)(addr += 4, addr - 4)
+#define F32S *(int32_t*)(addr += 4, addr - 4)
+#define F32S64 (uint64_t)(int64_t) F32S
+#define F64 *(uint64_t*)(addr += 8, addr - 8)
+#define PK(a) *(uint8_t*)(addr + a)
+#define PK16(a) *(uint16_t*)(addr + a)
+#define PK32(a) *(uint32_t*)(addr + a)
+#define PK64(a) *(uint64_t*)(addr + a)
+#define PKip(a) *(uint8_t*)(ip + a)
// Strong mem emulation helpers
-// Sequence of Read will trigger a DMB on "first" read if strongmem is 2
-// Squence of Write will trigger a DMB on "last" write if strongmem is 1
+#define SMREAD_MIN 2
+#define SMWRITE_MIN 1
+// Sequence of Read will trigger a DMB on "first" read if strongmem is >= SMREAD_MIN
+// Sequence of Write will trigger a DMB on "last" write if strongmem is >= 1
+// All Write operation that might use a lock all have a memory barrier if strongmem is >= SMWRITE_MIN
// Opcode will read
-#define SMREAD() if(!dyn->smread && box64_dynarec_strongmem>1) {SMDMB();}
+#define SMREAD(); if((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN)) {SMDMB();} else dyn->smread=1
// Opcode will read with option forced lock
-#define SMREADLOCK(lock) if(lock || (!dyn->smread && box64_dynarec_strongmem>1)) {SMDMB();}
-// Opcode migh read (depend on nextop)
+#define SMREADLOCK(lock) if((lock) || ((dyn->smread==0) && (box64_dynarec_strongmem>SMREAD_MIN))) {SMDMB();}
+// Opcode might read (depend on nextop)
#define SMMIGHTREAD() if(!MODREG) {SMREAD();}
// Opcode has wrote
#define SMWRITE() dyn->smwrite=1
// Opcode has wrote (strongmem>1 only)
-#define SMWRITE2() if(box64_dynarec_strongmem>1) dyn->smwrite=1
+#define SMWRITE2() if(box64_dynarec_strongmem>SMREAD_MIN) dyn->smwrite=1
// Opcode has wrote with option forced lock
-#define SMWRITELOCK(lock) if(lock) {SMDMB();} else dyn->smwrite=1
-// Opcode migh have wrote (depend on nextop)
+#define SMWRITELOCK(lock) if(lock || (box64_dynarec_strongmem>SMWRITE_MIN)) {SMDMB();} else dyn->smwrite=1
+// Opcode might have wrote (depend on nextop)
#define SMMIGHTWRITE() if(!MODREG) {SMWRITE();}
// Start of sequence
#define SMSTART() SMEND()
@@ -57,370 +60,471 @@
// Force a Data memory barrier (for LOCK: prefix)
#define SMDMB() FENCE(); dyn->smwrite=0; dyn->smread=1
-//LOCK_* define
-#define LOCK_LOCK (int*)1
+// LOCK_* define
+#define LOCK_LOCK (int*)1
// GETGD get x64 register in gd
-#define GETGD gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3)
+#define GETGD gd = xRAX + ((nextop & 0x38) >> 3) + (rex.r << 3)
// GETED can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
-#define GETED(D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD() \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
- LDxw(x1, wback, fixedaddress); \
- ed = x1; \
- }
+#define GETED(D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+ LDxw(x1, wback, fixedaddress); \
+ ed = x1; \
+ }
// GETSED can use r1 for ed, and r2 for wback. ed will be sign extended!
-#define GETSED(D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- if(!rex.w) { \
- ADDW(x1, ed, xZR); \
- ed = x1; \
- } \
- } else { \
- SMREAD() \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
- if(rex.w) \
- LD(x1, wback, fixedaddress); \
- else \
- LW(x1, wback, fixedaddress); \
- ed = x1; \
- }
+#define GETSED(D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ if (!rex.w) { \
+ ADDW(x1, ed, xZR); \
+ ed = x1; \
+ } \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+ if (rex.w) \
+ LD(x1, wback, fixedaddress); \
+ else \
+ LW(x1, wback, fixedaddress); \
+ ed = x1; \
+ }
// GETEDx can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
-#define GETEDx(D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD() \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
- LD(x1, wback, fixedaddress); \
- ed = x1; \
- }
-#define GETEDz(D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD() \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
- LDz(x1, wback, fixedaddress); \
- ed = x1; \
- }
+#define GETEDx(D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+ LD(x1, wback, fixedaddress); \
+ ed = x1; \
+ }
+#define GETEDz(D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+ LDz(x1, wback, fixedaddress); \
+ ed = x1; \
+ }
// GETED32 can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
-#define GETED32(D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD() \
- addr = geted32(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
- LDxw(x1, wback, fixedaddress); \
- ed = x1; \
- }
-//GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI
-#define GETEDH(hint, D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, (hint==x2)?x1:x2, (hint==x1)?x1:x3, &fixedaddress, rex, NULL, 1, D); \
- LDxw(hint, wback, fixedaddress); \
- ed = hint; \
- }
-//GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
-#define GETEDW(hint, ret, D) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- MV(ret, ed); \
- wback = 0; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, (hint==x2)?x1:x2, (hint==x1)?x1:x3, &fixedaddress, rex, NULL, 0, D); \
- ed = ret; \
- LDxw(ed, wback, fixedaddress); \
- }
+#define GETED32(D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted32(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+ LDxw(x1, wback, fixedaddress); \
+ ed = x1; \
+ }
+// GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI
+#define GETEDH(hint, D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 1, D); \
+ LDxw(hint, wback, fixedaddress); \
+ ed = hint; \
+ }
+// GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
+#define GETEDW(hint, ret, D) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ MV(ret, ed); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \
+ ed = ret; \
+ LDxw(ed, wback, fixedaddress); \
+ }
// GETGW extract x64 register in gd, that is i
-#define GETGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); ZEXTH(i, gd); gd = i;
-//GETEWW will use i for ed, and can use w for wback.
-#define GETEWW(w, i, D) if(MODREG) { \
- wback = xRAX+(nextop&7)+(rex.b<<3);\
- ZEXTH(i, wback); \
- ed = i; \
- wb1 = 0; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, w, i, &fixedaddress, rex, NULL, 1, D); \
- LHU(i, wback, fixedaddress);\
- ed = i; \
- wb1 = 1; \
- }
-//GETEW will use i for ed, and can use r3 for wback.
+#define GETGW(i) \
+ gd = xRAX + ((nextop & 0x38) >> 3) + (rex.r << 3); \
+ ZEXTH(i, gd); \
+ gd = i;
+// GETEWW will use i for ed, and can use w for wback.
+#define GETEWW(w, i, D) \
+ if (MODREG) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ ZEXTH(i, wback); \
+ ed = i; \
+ wb1 = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, w, i, &fixedaddress, rex, NULL, 1, D); \
+ LHU(i, wback, fixedaddress); \
+ ed = i; \
+ wb1 = 1; \
+ }
+// GETEW will use i for ed, and can use r3 for wback.
#define GETEW(i, D) GETEWW(x3, i, D)
-//GETSEW will use i for ed, and can use r3 for wback. This is the Signed version
-#define GETSEW(i, D) if(MODREG) { \
- wback = xRAX+(nextop&7)+(rex.b<<3);\
- if(rv64_zbb) SEXTH(i, wback); else {SLLI(i, wback, 48); SRAI(i, i, 48);}\
- ed = i; \
- wb1 = 0; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x3, i, &fixedaddress, rex, NULL, 1, D); \
- LH(i, wback, fixedaddress); \
- ed = i; \
- wb1 = 1; \
- }
+// GETSEW will use i for ed, and can use r3 for wback. This is the Signed version
+#define GETSEW(i, D) \
+ if (MODREG) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ if (rv64_zbb) \
+ SEXTH(i, wback); \
+ else { \
+ SLLI(i, wback, 48); \
+ SRAI(i, i, 48); \
+ } \
+ ed = i; \
+ wb1 = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, i, &fixedaddress, rex, NULL, 1, D); \
+ LH(i, wback, fixedaddress); \
+ ed = i; \
+ wb1 = 1; \
+ }
// Write ed back to original register / memory
-#define EWBACK EWBACKW(ed)
+#define EWBACK EWBACKW(ed)
// Write w back to original register / memory (w needs to be 16bits only!)
-#define EWBACKW(w) if(wb1) {SH(w, wback, fixedaddress); SMWRITE();} else {SRLI(wback, wback, 16); SLLI(wback, wback, 16); OR(wback, wback, w);}
+#define EWBACKW(w) \
+ if (wb1) { \
+ SH(w, wback, fixedaddress); \
+ SMWRITE(); \
+ } else { \
+ SRLI(wback, wback, 16); \
+ SLLI(wback, wback, 16); \
+ OR(wback, wback, w); \
+ }
// Write back gd in correct register (gd needs to be 16bits only!)
-#define GWBACK do{int g=xRAX+((nextop&0x38)>>3)+(rex.r<<3); SRLI(g, g, 16); SLLI(g, g, 16); OR(g, g, gd);}while(0)
-
-//GETEDO can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
-#define GETEDO(O, D, S) if(MODREG) { \
- ed = xRAX+(nextop&7)+(rex.b<<3); \
- wback = 0; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, S, &fixedaddress, rex, NULL, 1, D); \
- ADD(S, wback, O); \
- LDxw(x1, S, fixedaddress); \
- ed = x1; \
- }
-#define WBACKO(O) if(wback) {ADD(O, wback, O); SDxw(ed, O, 0); SMWRITE2();}
+#define GWBACK \
+ do { \
+ int g = xRAX + ((nextop & 0x38) >> 3) + (rex.r << 3); \
+ SRLI(g, g, 16); \
+ SLLI(g, g, 16); \
+ OR(g, g, gd); \
+ } while (0)
+
+// GETEDO can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
+#define GETEDO(O, D, S) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, S, &fixedaddress, rex, NULL, 1, D); \
+ ADD(S, wback, O); \
+ LDxw(x1, S, fixedaddress); \
+ ed = x1; \
+ }
+// GETEDOz can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
+#define GETEDOz(O, D, S) \
+ if (MODREG) { \
+ ed = xRAX + (nextop & 7) + (rex.b << 3); \
+ wback = 0; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, S, &fixedaddress, rex, NULL, 1, D); \
+ ADD(S, wback, O); \
+ LDz(x1, S, fixedaddress); \
+ ed = x1; \
+ }
+#define WBACKO(O) \
+ if (wback) { \
+ ADD(O, wback, O); \
+ SDxw(ed, O, 0); \
+ SMWRITE2(); \
+ }
// FAKEED like GETED, but doesn't get anything
-#define FAKEED if(!MODREG) { \
- addr = fakeed(dyn, addr, ninst, nextop); \
- }
+#define FAKEED \
+ if (!MODREG) { \
+ addr = fakeed(dyn, addr, ninst, nextop); \
+ }
// GETGW extract x64 register in gd, that is i, Signed extented
-#define GETSGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); SLLIW(i, gd, 16); SRAIW(i, i, 16); gd = i;
+#define GETSGW(i) \
+ gd = xRAX + ((nextop & 0x38) >> 3) + (rex.r << 3); \
+ SLLIW(i, gd, 16); \
+ SRAIW(i, i, 16); \
+ gd = i;
// Write back ed in wback (if wback not 0)
-#define WBACK if(wback) {SDxw(ed, wback, fixedaddress); SMWRITE();}
+#define WBACK \
+ if (wback) { \
+ SDxw(ed, wback, fixedaddress); \
+ SMWRITE(); \
+ }
// GETEB will use i for ed, and can use r3 for wback.
-#define GETEB(i, D) if(MODREG) { \
- if(rex.rex) { \
- wback = xRAX+(nextop&7)+(rex.b<<3); \
- wb2 = 0; \
- } else { \
- wback = (nextop&7); \
- wb2 = (wback>>2)*8; \
- wback = xRAX+(wback&3); \
- } \
- if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \
- wb1 = 0; \
- ed = i; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
- LBU(i, wback, fixedaddress);\
- wb1 = 1; \
- ed = i; \
- }
-//GETEBO will use i for ed, i is also Offset, and can use r3 for wback.
-#define GETEBO(i, D) if(MODREG) { \
- if(rex.rex) { \
- wback = xRAX+(nextop&7)+(rex.b<<3); \
- wb2 = 0; \
- } else { \
- wback = (nextop&7); \
- wb2 = (wback>>2)*8; \
- wback = xRAX+(wback&3); \
- } \
- if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \
- wb1 = 0; \
- ed = i; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
- ADD(x3, wback, i); \
- if(wback!=x3) wback = x3; \
- LBU(i, wback, fixedaddress);\
- wb1 = 1; \
- ed = i; \
- }
-//GETSEB sign extend EB, will use i for ed, and can use r3 for wback.
-#define GETSEB(i, D) if(MODREG) { \
- if(rex.rex) { \
- wback = xRAX+(nextop&7)+(rex.b<<3); \
- wb2 = 0; \
- } else { \
- wback = (nextop&7); \
- wb2 = (wback>>2)*8; \
- wback = xRAX+(wback&3); \
- } \
- MV(i, wback); \
- SLLIW(i, i, 24-wb2); \
- SRAIW(i, i, 24); \
- wb1 = 0; \
- ed = i; \
- } else { \
- SMREAD(); \
- addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, D); \
- LB(i, wback, fixedaddress); \
- wb1 = 1; \
- ed = i; \
- }
+#define GETEB(i, D) \
+ if (MODREG) { \
+ if (rex.rex) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ wb2 = 0; \
+ } else { \
+ wback = (nextop & 7); \
+ wb2 = (wback >> 2) * 8; \
+ wback = xRAX + (wback & 3); \
+ } \
+ if (wb2) { \
+ if (rv64_xtheadbb) { \
+ TH_EXTU(i, wback, 15, 8); \
+ } else { \
+ MV(i, wback); \
+ SRLI(i, i, wb2); \
+ ANDI(i, i, 0xff); \
+ } \
+ } else \
+ ANDI(i, wback, 0xff); \
+ wb1 = 0; \
+ ed = i; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
+ LBU(i, wback, fixedaddress); \
+ wb1 = 1; \
+ ed = i; \
+ }
+// GETEBO will use i for ed, i is also Offset, and can use r3 for wback.
+#define GETEBO(i, D) \
+ if (MODREG) { \
+ if (rex.rex) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ wb2 = 0; \
+ } else { \
+ wback = (nextop & 7); \
+ wb2 = (wback >> 2) * 8; \
+ wback = xRAX + (wback & 3); \
+ } \
+ if (wb2) { \
+ if (rv64_xtheadbb) { \
+ TH_EXTU(i, wback, 15, 8); \
+ } else { \
+ MV(i, wback); \
+ SRLI(i, i, wb2); \
+ ANDI(i, i, 0xff); \
+ } \
+ } else \
+ ANDI(i, wback, 0xff); \
+ wb1 = 0; \
+ ed = i; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
+ ADD(x3, wback, i); \
+ if (wback != x3) wback = x3; \
+ LBU(i, wback, fixedaddress); \
+ wb1 = 1; \
+ ed = i; \
+ }
+// GETSEB sign extend EB, will use i for ed, and can use r3 for wback.
+#define GETSEB(i, D) \
+ if (MODREG) { \
+ if (rex.rex) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ wb2 = 0; \
+ } else { \
+ wback = (nextop & 7); \
+ wb2 = (wback >> 2) * 8; \
+ wback = xRAX + (wback & 3); \
+ } \
+ MV(i, wback); \
+ SLLIW(i, i, 24 - wb2); \
+ SRAIW(i, i, 24); \
+ wb1 = 0; \
+ ed = i; \
+ } else { \
+ SMREAD(); \
+ addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, D); \
+ LB(i, wback, fixedaddress); \
+ wb1 = 1; \
+ ed = i; \
+ }
// GETEB32 will use i for ed, and can use r3 for wback.
-#define GETEB32(i, D) if(MODREG) { \
- if(rex.rex) { \
- wback = xRAX+(nextop&7)+(rex.b<<3); \
- wb2 = 0; \
- } else { \
- wback = (nextop&7); \
- wb2 = (wback>>2)*8; \
- wback = xRAX+(wback&3); \
- } \
- if (wb2) {MV(i, wback); SRLI(i, i, wb2); ANDI(i, i, 0xff);} else {ANDI(i, wback, 0xff);} \
- wb1 = 0; \
- ed = i; \
- } else { \
- SMREAD(); \
- addr = geted32(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
- LBU(i, wback, fixedaddress);\
- wb1 = 1; \
- ed = i; \
- }
-
-//GETGB will use i for gd
-#define GETGB(i) if(rex.rex) { \
- gb1 = xRAX+((nextop&0x38)>>3)+(rex.r<<3); \
- gb2 = 0; \
- } else { \
- gd = (nextop&0x38)>>3; \
- gb2 = ((gd&4)>>2); \
- gb1 = xRAX+(gd&3); \
- } \
- gd = i; \
- if (gb2) {MV(gd, gb1); SRLI(gd, gd, 8); ANDI(gd, gd, 0xff);} else {ANDI(gd, gb1, 0xff);}
+#define GETEB32(i, D) \
+ if (MODREG) { \
+ if (rex.rex) { \
+ wback = xRAX + (nextop & 7) + (rex.b << 3); \
+ wb2 = 0; \
+ } else { \
+ wback = (nextop & 7); \
+ wb2 = (wback >> 2) * 8; \
+ wback = xRAX + (wback & 3); \
+ } \
+ if (wb2) { \
+ if (rv64_xtheadbb) { \
+ TH_EXTU(i, wback, 15, 8); \
+ } else { \
+ MV(i, wback); \
+ SRLI(i, i, wb2); \
+ ANDI(i, i, 0xff); \
+ } \
+ } else \
+ ANDI(i, wback, 0xff); \
+ wb1 = 0; \
+ ed = i; \
+ } else { \
+ SMREAD(); \
+ addr = geted32(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
+ LBU(i, wback, fixedaddress); \
+ wb1 = 1; \
+ ed = i; \
+ }
+
+// GETGB will use i for gd
+#define GETGB(i) \
+ if (rex.rex) { \
+ gb1 = xRAX + ((nextop & 0x38) >> 3) + (rex.r << 3); \
+ gb2 = 0; \
+ } else { \
+ gd = (nextop & 0x38) >> 3; \
+ gb2 = ((gd & 4) >> 2); \
+ gb1 = xRAX + (gd & 3); \
+ } \
+ gd = i; \
+ if (gb2) { \
+ if (rv64_xtheadbb) { \
+ TH_EXTU(gd, gb1, 15, 8); \
+ } else { \
+ MV(gd, gb1); \
+ SRLI(gd, gd, 8); \
+ ANDI(gd, gd, 0xff); \
+ } \
+ } else \
+ ANDI(gd, gb1, 0xff);
// Write gb (gd) back to original register / memory, using s1 as scratch
-#define GBBACK(s1) if(gb2) { \
- MOV64x(s1, 0xffffffffffff00ffLL); \
- AND(gb1, gb1, s1); \
- SLLI(s1, gd, 8); \
- OR(gb1, gb1, s1); \
- } else { \
- ANDI(gb1, gb1, ~0xff); \
- OR(gb1, gb1, gd); \
- }
+#define GBBACK(s1) \
+ if (gb2) { \
+ MOV64x(s1, 0xffffffffffff00ffLL); \
+ AND(gb1, gb1, s1); \
+ SLLI(s1, gd, 8); \
+ OR(gb1, gb1, s1); \
+ } else { \
+ ANDI(gb1, gb1, ~0xff); \
+ OR(gb1, gb1, gd); \
+ }
// Write eb (ed) back to original register / memory, using s1 as scratch
-#define EBBACK(s1, c) if(wb1) { \
- SB(ed, wback, fixedaddress); \
- SMWRITE(); \
- } else if(wb2) { \
- MOV64x(s1, 0xffffffffffff00ffLL); \
- AND(wback, wback, s1); \
- if (c) {ANDI(ed, ed, 0xff);} \
- SLLI(s1, ed, 8); \
- OR(wback, wback, s1); \
- } else { \
- ANDI(wback, wback, ~0xff); \
- if (c) {ANDI(ed, ed, 0xff);} \
- OR(wback, wback, ed); \
- }
+#define EBBACK(s1, c) \
+ if (wb1) { \
+ SB(ed, wback, fixedaddress); \
+ SMWRITE(); \
+ } else if (wb2) { \
+ MOV64x(s1, 0xffffffffffff00ffLL); \
+ AND(wback, wback, s1); \
+ if (c) { ANDI(ed, ed, 0xff); } \
+ SLLI(s1, ed, 8); \
+ OR(wback, wback, s1); \
+ } else { \
+ ANDI(wback, wback, ~0xff); \
+ if (c) { ANDI(ed, ed, 0xff); } \
+ OR(wback, wback, ed); \
+ }
// Get direction with size Z and based of F_DF flag, on register r ready for load/store fetching
// using s as scratch.
-#define GETDIR(r, s, Z) \
- MOV32w(r, Z); /* mask=1<<10 */ \
- ANDI(s, xFlags, 1<<F_DF); \
- BEQZ(s, 8); \
- SUB(r, xZR, r); \
+#define GETDIR(r, s, Z) \
+ MOV32w(r, Z); /* mask=1<<10 */ \
+ ANDI(s, xFlags, 1 << F_DF); \
+ BEQZ(s, 8); \
+ SUB(r, xZR, r);
// Generic get GD, but reg value in gd (R_RAX is not added)
-#define GETG gd = ((nextop&0x38)>>3)+(rex.r<<3)
+#define GETG gd = ((nextop & 0x38) >> 3) + (rex.r << 3)
// Get GX as a Single (might use x2)
-#define GETGXSS(a) \
- gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+#define GETGXSS(a) \
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
a = sse_get_reg(dyn, ninst, x2, gd, 1)
// Get GX as a Single (might use x2), no fetching old value
-#define GETGXSS_empty(a) \
- gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+#define GETGXSS_empty(a) \
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
a = sse_get_reg_empty(dyn, ninst, x2, gd, 1)
// Get GX as a Double (might use x2)
-#define GETGXSD(a) \
- gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+#define GETGXSD(a) \
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
a = sse_get_reg(dyn, ninst, x2, gd, 0)
// Get GX as a Double (might use x2), no fetching old value
-#define GETGXSD_empty(a) \
- gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+#define GETGXSD_empty(a) \
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
a = sse_get_reg_empty(dyn, ninst, x2, gd, 0)
// Get Ex as a single, not a quad (warning, x1 get used, x2 might too)
-#define GETEXSS(a, D) \
- if(MODREG) { \
- a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1); \
- } else { \
- SMREAD(); \
- a = fpu_get_scratch(dyn); \
- addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
- FLW(a, ed, fixedaddress); \
+#define GETEXSS(a, D) \
+ if (MODREG) { \
+ a = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 1); \
+ } else { \
+ SMREAD(); \
+ a = fpu_get_scratch(dyn); \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
+ FLW(a, ed, fixedaddress); \
}
// Get Ex as a double, not a quad (warning, x1 get used, x2 might too)
-#define GETEXSD(a, D) \
- if(MODREG) { \
- a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0); \
- } else { \
- SMREAD(); \
- a = fpu_get_scratch(dyn); \
- addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
- FLD(a, ed, fixedaddress); \
+#define GETEXSD(a, D) \
+ if (MODREG) { \
+ a = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0); \
+ } else { \
+ SMREAD(); \
+ a = fpu_get_scratch(dyn); \
+ addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
+ FLD(a, ed, fixedaddress); \
}
// Will get pointer to GX in general register a, will purge SS or SD if loaded. can use gback as load address
-#define GETGX() \
- gd = ((nextop&0x38)>>3)+(rex.r<<3); \
- sse_forget_reg(dyn, ninst, gd); \
- gback = xEmu; \
+#define GETGX() \
+ gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \
+ sse_forget_reg(dyn, ninst, gd); \
+ gback = xEmu; \
gdoffset = offsetof(x64emu_t, xmm[gd])
// Get Ex address in general register a, will purge SS or SD if it's reg and is loaded. May use x3. Use wback as load address!
-#define GETEX(a, D) \
- if(MODREG) { \
- ed = (nextop&7)+(rex.b<<3); \
- sse_forget_reg(dyn, ninst, ed); \
- fixedaddress = offsetof(x64emu_t, xmm[ed]); \
- wback = xEmu; \
- } else { \
- SMREAD(); \
- ed=16; \
- addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \
+#define GETEX(a, D) \
+ if (MODREG) { \
+ ed = (nextop & 7) + (rex.b << 3); \
+ sse_forget_reg(dyn, ninst, ed); \
+ fixedaddress = offsetof(x64emu_t, xmm[ed]); \
+ wback = xEmu; \
+ } else { \
+ SMREAD(); \
+ ed = 16; \
+ addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \
}
-#define GETGM() \
- gd = ((nextop&0x38)>>3); \
- mmx_forget_reg(dyn, ninst, gd); \
- gback = xEmu; \
+#define GETGM() \
+ gd = ((nextop & 0x38) >> 3); \
+ mmx_forget_reg(dyn, ninst, gd); \
+ gback = xEmu; \
gdoffset = offsetof(x64emu_t, mmx[gd])
// Get EM, might use x3
-#define GETEM(a, D) \
- if(MODREG) { \
- ed = (nextop&7); \
- mmx_forget_reg(dyn, ninst, ed); \
- fixedaddress = offsetof(x64emu_t, mmx[ed]); \
- wback = xEmu; \
- } else { \
- SMREAD(); \
- ed=8; \
- addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \
+#define GETEM(a, D) \
+ if (MODREG) { \
+ ed = (nextop & 7); \
+ mmx_forget_reg(dyn, ninst, ed); \
+ fixedaddress = offsetof(x64emu_t, mmx[ed]); \
+ wback = xEmu; \
+ } else { \
+ SMREAD(); \
+ ed = 8; \
+ addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \
}
-#define SSE_LOOP_D_ITEM(GX1, EX1, F, i) \
- LWU(GX1, gback, gdoffset+i*4); \
- LWU(EX1, wback, fixedaddress+i*4); \
- F; \
- SW(GX1, gback, gdoffset+i*4);
+#define SSE_LOOP_D_ITEM(GX1, EX1, F, i) \
+ LWU(GX1, gback, gdoffset + i * 4); \
+ LWU(EX1, wback, fixedaddress + i * 4); \
+ F; \
+ SW(GX1, gback, gdoffset + i * 4);
// Loop for SSE opcode that use 32bits value and write to GX.
#define SSE_LOOP_D(GX1, EX1, F) \
@@ -429,11 +533,11 @@
SSE_LOOP_D_ITEM(GX1, EX1, F, 2) \
SSE_LOOP_D_ITEM(GX1, EX1, F, 3)
-#define SSE_LOOP_DS_ITEM(GX1, EX1, F, i) \
- LW(GX1, gback, gdoffset+i*4); \
- LW(EX1, wback, fixedaddress+i*4); \
- F; \
- SW(GX1, gback, gdoffset+i*4);
+#define SSE_LOOP_DS_ITEM(GX1, EX1, F, i) \
+ LW(GX1, gback, gdoffset + i * 4); \
+ LW(EX1, wback, fixedaddress + i * 4); \
+ F; \
+ SW(GX1, gback, gdoffset + i * 4);
// Loop for SSE opcode that use 32bits value and write to GX.
#define SSE_LOOP_DS(GX1, EX1, F) \
@@ -442,34 +546,50 @@
SSE_LOOP_DS_ITEM(GX1, EX1, F, 2) \
SSE_LOOP_DS_ITEM(GX1, EX1, F, 3)
-#define MMX_LOOP_W(GX1, EX1, F) \
- for (int i=0; i<4; ++i) { \
- LHU(GX1, gback, gdoffset+i*2); \
- LHU(EX1, wback, fixedaddress+i*2); \
- F; \
- SH(GX1, gback, gdoffset+i*2); \
+#define MMX_LOOP_D(GX1, EX1, F) \
+ for (int i = 0; i < 2; ++i) { \
+ LWU(GX1, gback, gdoffset + i * 4); \
+ LWU(EX1, wback, fixedaddress + i * 4); \
+ F; \
+ SW(GX1, gback, gdoffset + i * 4); \
+ }
+
+#define MMX_LOOP_W(GX1, EX1, F) \
+ for (int i = 0; i < 4; ++i) { \
+ LHU(GX1, gback, gdoffset + i * 2); \
+ LHU(EX1, wback, fixedaddress + i * 2); \
+ F; \
+ SH(GX1, gback, gdoffset + i * 2); \
}
-#define SSE_LOOP_W(GX1, EX1, F) \
- for (int i=0; i<8; ++i) { \
- LHU(GX1, gback, gdoffset+i*2); \
- LHU(EX1, wback, fixedaddress+i*2); \
- F; \
- SH(GX1, gback, gdoffset+i*2); \
+#define MMX_LOOP_WS(GX1, EX1, F) \
+ for (int i = 0; i < 4; ++i) { \
+ LH(GX1, gback, gdoffset + i * 2); \
+ LH(EX1, wback, fixedaddress + i * 2); \
+ F; \
+ SH(GX1, gback, gdoffset + i * 2); \
}
-#define SSE_LOOP_WS(GX1, EX1, F) \
- for (int i=0; i<8; ++i) { \
- LH(GX1, gback, gdoffset+i*2); \
- LH(EX1, wback, fixedaddress+i*2); \
- F; \
- SH(GX1, gback, gdoffset+i*2); \
+#define SSE_LOOP_W(GX1, EX1, F) \
+ for (int i = 0; i < 8; ++i) { \
+ LHU(GX1, gback, gdoffset + i * 2); \
+ LHU(EX1, wback, fixedaddress + i * 2); \
+ F; \
+ SH(GX1, gback, gdoffset + i * 2); \
}
-#define SSE_LOOP_D_S_ITEM(EX1, F, i) \
- LWU(EX1, wback, fixedaddress+i*4); \
- F; \
- SW(EX1, wback, fixedaddress+i*4);
+#define SSE_LOOP_WS(GX1, EX1, F) \
+ for (int i = 0; i < 8; ++i) { \
+ LH(GX1, gback, gdoffset + i * 2); \
+ LH(EX1, wback, fixedaddress + i * 2); \
+ F; \
+ SH(GX1, gback, gdoffset + i * 2); \
+ }
+
+#define SSE_LOOP_D_S_ITEM(EX1, F, i) \
+ LWU(EX1, wback, fixedaddress + i * 4); \
+ F; \
+ SW(EX1, wback, fixedaddress + i * 4);
// Loop for SSE opcode that use 32bits value and write to EX.
#define SSE_LOOP_D_S(EX1, F) \
@@ -478,11 +598,11 @@
SSE_LOOP_D_S_ITEM(EX1, F, 2) \
SSE_LOOP_D_S_ITEM(EX1, F, 3)
-#define SSE_LOOP_Q_ITEM(GX1, EX1, F, i) \
- LD(GX1, gback, gdoffset+i*8); \
- LD(EX1, wback, fixedaddress+i*8); \
- F; \
- SD(GX1, gback, gdoffset+i*8);
+#define SSE_LOOP_Q_ITEM(GX1, EX1, F, i) \
+ LD(GX1, gback, gdoffset + i * 8); \
+ LD(EX1, wback, fixedaddress + i * 8); \
+ F; \
+ SD(GX1, gback, gdoffset + i * 8);
// Loop for SSE opcode that use 64bits value and write to GX.
#define SSE_LOOP_Q(GX1, EX1, F) \
@@ -490,11 +610,11 @@
SSE_LOOP_Q_ITEM(GX1, EX1, F, 1)
-#define SSE_LOOP_FQ_ITEM(GX1, EX1, F, i) \
- FLD(v0, gback, gdoffset+i*8); \
- FLD(v1, wback, fixedaddress+i*8); \
- F; \
- FSD(v0, gback, gdoffset+i*8);
+#define SSE_LOOP_FQ_ITEM(GX1, EX1, F, i) \
+ FLD(v0, gback, gdoffset + i * 8); \
+ FLD(v1, wback, fixedaddress + i * 8); \
+ F; \
+ FSD(v0, gback, gdoffset + i * 8);
#define SSE_LOOP_FQ(GX1, EX1, F) \
v0 = fpu_get_scratch(dyn); \
@@ -503,18 +623,18 @@
SSE_LOOP_FQ_ITEM(GX1, EX1, F, 1)
-#define SSE_LOOP_MV_Q_ITEM(s, i) \
- LD(s, wback, fixedaddress+i*8); \
- SD(s, gback, gdoffset+i*8);
+#define SSE_LOOP_MV_Q_ITEM(s, i) \
+ LD(s, wback, fixedaddress + i * 8); \
+ SD(s, gback, gdoffset + i * 8);
// Loop for SSE opcode that moves 64bits value from wback to gback, use s as scratch.
#define SSE_LOOP_MV_Q(s) \
SSE_LOOP_MV_Q_ITEM(s, 0) \
SSE_LOOP_MV_Q_ITEM(s, 1)
-#define SSE_LOOP_MV_Q_ITEM2(s, i) \
- LD(s, gback, gdoffset+i*8); \
- SD(s, wback, fixedaddress+i*8);
+#define SSE_LOOP_MV_Q_ITEM2(s, i) \
+ LD(s, gback, gdoffset + i * 8); \
+ SD(s, wback, fixedaddress + i * 8);
// Loop for SSE opcode that moves 64bits value from gback to wback, use s as scratch.
#define SSE_LOOP_MV_Q2(s) \
@@ -531,49 +651,66 @@
// R0 will not be pushed/popd if ret is -2. Flags are not save/restored
#define CALL_S(F, ret) call_c(dyn, ninst, F, x6, ret, 0, 0)
-#define MARK dyn->insts[ninst].mark = dyn->native_size
-#define GETMARK dyn->insts[ninst].mark
-#define MARK2 dyn->insts[ninst].mark2 = dyn->native_size
-#define GETMARK2 dyn->insts[ninst].mark2
-#define MARK3 dyn->insts[ninst].mark3 = dyn->native_size
-#define GETMARK3 dyn->insts[ninst].mark3
-#define MARKF dyn->insts[ninst].markf = dyn->native_size
-#define GETMARKF dyn->insts[ninst].markf
-#define MARKF2 dyn->insts[ninst].markf2 = dyn->native_size
-#define GETMARKF2 dyn->insts[ninst].markf2
+#define MARKi(i) dyn->insts[ninst].mark[i] = dyn->native_size
+#define GETMARKi(i) dyn->insts[ninst].mark[i]
+#define MARK MARKi(0)
+#define GETMARK GETMARKi(0)
+#define MARK2 MARKi(1)
+#define GETMARK2 GETMARKi(1)
+#define MARK3 MARKi(2)
+#define GETMARK3 GETMARKi(2)
+
+#define MARKFi(i) dyn->insts[ninst].markf[i] = dyn->native_size
+#define GETMARKFi(i) dyn->insts[ninst].markf[i]
+#define MARKF MARKFi(0)
+#define GETMARKF GETMARKFi(0)
+#define MARKF2 MARKFi(1)
+#define GETMARKF2 GETMARKFi(1)
+
#define MARKSEG dyn->insts[ninst].markseg = dyn->native_size
#define GETMARKSEG dyn->insts[ninst].markseg
#define MARKLOCK dyn->insts[ninst].marklock = dyn->native_size
#define GETMARKLOCK dyn->insts[ninst].marklock
-#define Bxx_gen(OP, M, reg1, reg2) \
- j64 = GET##M - dyn->native_size; \
- B##OP (reg1, reg2, j64)
+#define Bxx_gen(OP, M, reg1, reg2) \
+ j64 = GET##M - dyn->native_size; \
+ B##OP(reg1, reg2, j64)
+
+#define Bxx_geni(OP, M, reg1, reg2, i) \
+ j64 = GET##M##i(i) - dyn->native_size; \
+ B##OP(reg1, reg2, j64)
// Branch to MARK if reg1==reg2 (use j64)
-#define BEQ_MARK(reg1, reg2) Bxx_gen(EQ, MARK, reg1, reg2)
+#define BEQ_MARK(reg1, reg2) Bxx_gen(EQ, MARK, reg1, reg2)
+#define BEQ_MARKi(reg1, reg2, i) Bxx_geni(EQ, MARK, reg1, reg2, i)
// Branch to MARK if reg1!=reg2 (use j64)
-#define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2)
+#define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2)
+#define BNE_MARKi(reg1, reg2, i) Bxx_geni(NE, MARK, reg1, reg2, i)
// Branch to MARK if reg1!=0 (use j64)
-#define BNEZ_MARK(reg) BNE_MARK(reg, xZR)
+#define BNEZ_MARK(reg) BNE_MARK(reg, xZR)
+#define BNEZ_MARKi(reg, i) BNE_MARKi(reg, xZR, i)
// Branch to MARK instruction unconditionnal (use j64)
-#define B_MARK_nocond Bxx_gen(__, MARK, 0, 0)
+#define B_MARK_nocond Bxx_gen(__, MARK, 0, 0)
+#define B_MARKi_nocond Bxx_geni(__, MARK, 0, 0, i)
// Branch to MARK if reg1<reg2 (use j64)
-#define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2)
+#define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2)
+#define BLT_MARKi(reg1, reg2) Bxx_geni(LT, MARK, reg1, reg2, i)
// Branch to MARK if reg1<reg2 (use j64)
-#define BLTU_MARK(reg1, reg2) Bxx_gen(LTU, MARK, reg1, reg2)
+#define BLTU_MARK(reg1, reg2) Bxx_gen(LTU, MARK, reg1, reg2)
+#define BLTU_MARKi(reg1, reg2) Bxx_geni(LTU, MARK, reg1, reg2, i)
// Branch to MARK if reg1>=reg2 (use j64)
-#define BGE_MARK(reg1, reg2) Bxx_gen(GE, MARK, reg1, reg2)
+#define BGE_MARK(reg1, reg2) Bxx_gen(GE, MARK, reg1, reg2)
+#define BGE_MARKi(reg1, reg2) Bxx_geni(GE, MARK, reg1, reg2, i)
// Branch to MARK2 if reg1==reg2 (use j64)
-#define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1,reg2)
+#define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1, reg2)
// Branch to MARK2 if reg1!=reg2 (use j64)
-#define BNE_MARK2(reg1, reg2) Bxx_gen(NE, MARK2, reg1,reg2)
+#define BNE_MARK2(reg1, reg2) Bxx_gen(NE, MARK2, reg1, reg2)
// Branch to MARK2 if reg1!=0 (use j64)
#define BNEZ_MARK2(reg) BNE_MARK2(reg, xZR)
// Branch to MARK2 if reg1<reg2 (use j64)
-#define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1,reg2)
+#define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1, reg2)
// Branch to MARK2 instruction unconditionnal (use j64)
-#define B_MARK2_nocond Bxx_gen(__, MARK2, 0, 0)
+#define B_MARK2_nocond Bxx_gen(__, MARK2, 0, 0)
// Branch to MARK3 if reg1==reg2 (use j64)
#define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2)
// Branch to MARK3 if reg1!=reg2 (use j64)
@@ -581,124 +718,157 @@
// Branch to MARK3 if reg1!=0 (use j64)
#define BNEZ_MARK3(reg) BNE_MARK3(reg, xZR)
// Branch to MARK3 instruction unconditionnal (use j64)
-#define B_MARK3_nocond Bxx_gen(__, MARK3, 0, 0)
+#define B_MARK3_nocond Bxx_gen(__, MARK3, 0, 0)
// Branch to MARKLOCK if reg1!=reg2 (use j64)
#define BNE_MARKLOCK(reg1, reg2) Bxx_gen(NE, MARKLOCK, reg1, reg2)
// Branch to MARKLOCK if reg1!=0 (use j64)
#define BNEZ_MARKLOCK(reg) BNE_MARKLOCK(reg, xZR)
// Branch to NEXT if reg1==reg2 (use j64)
-#define BEQ_NEXT(reg1, reg2) \
- j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; \
+#define BEQ_NEXT(reg1, reg2) \
+ j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; \
BEQ(reg1, reg2, j64)
// Branch to NEXT if reg1==0 (use j64)
-#define CBZ_NEXT(reg1) \
- j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; \
+#define CBZ_NEXT(reg1) \
+ j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; \
BEQ(reg1, xZR, j64)
// Branch to NEXT if reg1!=0 (use j64)
-#define CBNZ_NEXT(reg1) \
- j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; \
+#define CBNZ_NEXT(reg1) \
+ j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; \
BNE(reg1, xZR, j64)
// Branch to next instruction unconditionnal (use j64)
-#define B_NEXT_nocond \
- j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;\
+#define B_NEXT_nocond \
+ j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; \
B(j64)
// Branch to MARKSEG if reg is 0 (use j64)
-#define CBZ_MARKSEG(reg) \
- j64 = GETMARKSEG-(dyn->native_size); \
+#define CBZ_MARKSEG(reg) \
+ j64 = GETMARKSEG - (dyn->native_size); \
BEQZ(reg, j64);
// Branch to MARKSEG if reg is not 0 (use j64)
-#define CBNZ_MARKSEG(reg) \
- j64 = GETMARKSEG-(dyn->native_size); \
+#define CBNZ_MARKSEG(reg) \
+ j64 = GETMARKSEG - (dyn->native_size); \
BNEZ(reg, j64);
-#define IFX(A) if((dyn->insts[ninst].x64.gen_flags&(A)))
-#define IFX_PENDOR0 if((dyn->insts[ninst].x64.gen_flags&(X_PEND) || !dyn->insts[ninst].x64.gen_flags))
-#define IFXX(A) if((dyn->insts[ninst].x64.gen_flags==(A)))
-#define IFX2X(A, B) if((dyn->insts[ninst].x64.gen_flags==(A) || dyn->insts[ninst].x64.gen_flags==(B) || dyn->insts[ninst].x64.gen_flags==((A)|(B))))
-#define IFXN(A, B) if((dyn->insts[ninst].x64.gen_flags&(A) && !(dyn->insts[ninst].x64.gen_flags&(B))))
+#define IFX(A) if ((dyn->insts[ninst].x64.gen_flags & (A)))
+#define IFX_PENDOR0 if ((dyn->insts[ninst].x64.gen_flags & (X_PEND) || !dyn->insts[ninst].x64.gen_flags))
+#define IFXX(A) if ((dyn->insts[ninst].x64.gen_flags == (A)))
+#define IFX2X(A, B) if ((dyn->insts[ninst].x64.gen_flags == (A) || dyn->insts[ninst].x64.gen_flags == (B) || dyn->insts[ninst].x64.gen_flags == ((A) | (B))))
+#define IFXN(A, B) if ((dyn->insts[ninst].x64.gen_flags & (A) && !(dyn->insts[ninst].x64.gen_flags & (B))))
-#define STORE_REG(A) SD(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
-#define LOAD_REG(A) LD(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
+#define STORE_REG(A) SD(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
+#define LOAD_REG(A) LD(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
// Need to also store current value of some register, as they may be used by functions like setjmp
-#define STORE_XEMU_CALL() \
- STORE_REG(RBX); \
- STORE_REG(RDX); \
- STORE_REG(RSP); \
- STORE_REG(RBP); \
- STORE_REG(RDI); \
- STORE_REG(RSI); \
- STORE_REG(R8); \
- STORE_REG(R9); \
- STORE_REG(R10); \
- STORE_REG(R11); \
-
-#define LOAD_XEMU_CALL() \
-
-#define LOAD_XEMU_REM() \
- LOAD_REG(RBX); \
- LOAD_REG(RDX); \
- LOAD_REG(RSP); \
- LOAD_REG(RBP); \
- LOAD_REG(RDI); \
- LOAD_REG(RSI); \
- LOAD_REG(R8); \
- LOAD_REG(R9); \
- LOAD_REG(R10); \
- LOAD_REG(R11); \
-
-
-#define SET_DFNONE() if(!dyn->f.dfnone) {SW(xZR, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=1;}
-#define SET_DF(S, N) if((N)!=d_none) {MOV_U12(S, (N)); SW(S, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=0;} else SET_DFNONE()
-#define SET_NODF() dyn->f.dfnone = 0
-#define SET_DFOK() dyn->f.dfnone = 1
-
-#define CLEAR_FLAGS() IFX(X_ALL) {ANDI(xFlags, xFlags, ~((1UL<<F_AF) | (1UL<<F_CF) | (1UL<<F_OF2) | (1UL<<F_ZF) | (1UL<<F_SF) | (1UL<<F_PF)));}
-
-#define CALC_SUB_FLAGS(op1_, op2, res, scratch1, scratch2, width) \
- IFX(X_AF | X_CF | X_OF) { \
- /* calc borrow chain */ \
- /* bc = (res & (~op1 | op2)) | (~op1 & op2) */ \
- OR(scratch1, op1_, op2); \
- AND(scratch2, res, scratch1); \
- AND(op1_, op1_, op2); \
- OR(scratch2, scratch2, op1_); \
- IFX(X_AF) { \
- /* af = bc & 0x8 */ \
- ANDI(scratch1, scratch2, 8); \
- BEQZ(scratch1, 8); \
- ORI(xFlags, xFlags, 1 << F_AF); \
- } \
- IFX(X_CF) { \
- /* cf = bc & (1<<(width-1)) */ \
- if ((width) == 8) { \
- ANDI(scratch1, scratch2, 0x80); \
- } else { \
- SRLI(scratch1, scratch2, (width)-1); \
- if(width!=64) ANDI(scratch1, scratch1, 1); \
- } \
- BEQZ(scratch1, 8); \
- ORI(xFlags, xFlags, 1 << F_CF); \
- } \
- IFX(X_OF) { \
- /* of = ((bc >> (width-2)) ^ (bc >> (width-1))) & 0x1; */ \
- SRLI(scratch1, scratch2, (width)-2); \
- SRLI(scratch2, scratch1, 1); \
- XOR(scratch1, scratch1, scratch2); \
- ANDI(scratch1, scratch1, 1); \
- BEQZ(scratch1, 8); \
- ORI(xFlags, xFlags, 1 << F_OF2); \
- } \
+#define STORE_XEMU_CALL(s0) \
+ if (rv64_xtheadmempair) { \
+ ADDI(s0, xEmu, offsetof(x64emu_t, regs[_RSP])); \
+ TH_SDD(xRDX, xRBX, xEmu, 1); \
+ TH_SDD(xRSP, xRBP, s0, 0); \
+ TH_SDD(xRSI, xRDI, s0, 1); \
+ TH_SDD(xR8, xR9, s0, 2); \
+ TH_SDD(xR10, xR11, s0, 3); \
+ } else { \
+ STORE_REG(RBX); \
+ STORE_REG(RDX); \
+ STORE_REG(RSP); \
+ STORE_REG(RBP); \
+ STORE_REG(RDI); \
+ STORE_REG(RSI); \
+ STORE_REG(R8); \
+ STORE_REG(R9); \
+ STORE_REG(R10); \
+ STORE_REG(R11); \
+ }
+
+#define LOAD_XEMU_CALL()
+
+#define LOAD_XEMU_REM(s0) \
+ if (rv64_xtheadmempair) { \
+ ADDI(s0, xEmu, offsetof(x64emu_t, regs[_RSP])); \
+ TH_LDD(xRDX, xRBX, xEmu, 1); \
+ TH_LDD(xRSP, xRBP, s0, 0); \
+ TH_LDD(xRSI, xRDI, s0, 1); \
+ TH_LDD(xR8, xR9, s0, 2); \
+ TH_LDD(xR10, xR11, s0, 3); \
+ } else { \
+ LOAD_REG(RBX); \
+ LOAD_REG(RDX); \
+ LOAD_REG(RSP); \
+ LOAD_REG(RBP); \
+ LOAD_REG(RDI); \
+ LOAD_REG(RSI); \
+ LOAD_REG(R8); \
+ LOAD_REG(R9); \
+ LOAD_REG(R10); \
+ LOAD_REG(R11); \
+ }
+
+
+#define SET_DFNONE() \
+ if (!dyn->f.dfnone) { \
+ SW(xZR, xEmu, offsetof(x64emu_t, df)); \
+ dyn->f.dfnone = 1; \
+ }
+#define SET_DF(S, N) \
+ if ((N) != d_none) { \
+ MOV_U12(S, (N)); \
+ SW(S, xEmu, offsetof(x64emu_t, df)); \
+ dyn->f.dfnone = 0; \
+ } else \
+ SET_DFNONE()
+#define SET_NODF() dyn->f.dfnone = 0
+#define SET_DFOK() dyn->f.dfnone = 1
+
+#define CLEAR_FLAGS() \
+ IFX(X_ALL) { ANDI(xFlags, xFlags, ~((1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF2) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF))); }
+
+#define CALC_SUB_FLAGS(op1_, op2, res, scratch1, scratch2, width) \
+ IFX(X_AF | X_CF | X_OF) \
+ { \
+ /* calc borrow chain */ \
+ /* bc = (res & (~op1 | op2)) | (~op1 & op2) */ \
+ OR(scratch1, op1_, op2); \
+ AND(scratch2, res, scratch1); \
+ AND(op1_, op1_, op2); \
+ OR(scratch2, scratch2, op1_); \
+ IFX(X_AF) \
+ { \
+ /* af = bc & 0x8 */ \
+ ANDI(scratch1, scratch2, 8); \
+ BEQZ(scratch1, 8); \
+ ORI(xFlags, xFlags, 1 << F_AF); \
+ } \
+ IFX(X_CF) \
+ { \
+ /* cf = bc & (1<<(width-1)) */ \
+ if ((width) == 8) { \
+ ANDI(scratch1, scratch2, 0x80); \
+ } else { \
+ SRLI(scratch1, scratch2, (width)-1); \
+ if (width != 64) ANDI(scratch1, scratch1, 1); \
+ } \
+ BEQZ(scratch1, 8); \
+ ORI(xFlags, xFlags, 1 << F_CF); \
+ } \
+ IFX(X_OF) \
+ { \
+ /* of = ((bc >> (width-2)) ^ (bc >> (width-1))) & 0x1; */ \
+ SRLI(scratch1, scratch2, (width)-2); \
+ SRLI(scratch2, scratch1, 1); \
+ XOR(scratch1, scratch1, scratch2); \
+ ANDI(scratch1, scratch1, 1); \
+ BEQZ(scratch1, 8); \
+ ORI(xFlags, xFlags, 1 << F_OF2); \
+ } \
}
// Adjust the xFlags bit 11 -> bit 5, result in reg (can be xFlags, but not s1)
-#define FLAGS_ADJUST_FROM11(reg, s1)\
- ANDI(reg, xFlags, ~(1<<5)); \
- SRLI(s1, reg, 11-5); \
- ANDI(s1, s1, 1<<5); \
+#define FLAGS_ADJUST_FROM11(reg, s1) \
+ ANDI(reg, xFlags, ~(1 << 5)); \
+ SRLI(s1, reg, 11 - 5); \
+ ANDI(s1, s1, 1 << 5); \
OR(reg, reg, s1)
// Adjust the xFlags bit 5 -> bit 11, src and dst can be the same (and can be xFlags, but not s1)
@@ -706,46 +876,70 @@
LUI(s1, 0xFFFFF); \
ADDIW(s1, s1, 0x7DF); \
AND(s1, src, s1); \
- ANDI(dst, src, 1<<5); \
- SLLI(dst, dst, 11-5); \
+ ANDI(dst, src, 1 << 5); \
+ SLLI(dst, dst, 11 - 5); \
OR(dst, dst, s1)
+#define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \
+ if (dyn->e.stack == +8) { \
+ *ok = 0; \
+ break; \
+ } \
+ var = x87_do_push(dyn, ninst, scratch, t);
+
+#define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \
+ if (dyn->e.stack == +8) { \
+ *ok = 0; \
+ break; \
+ } \
+ x87_do_push_empty(dyn, ninst, scratch);
+
+#define X87_POP_OR_FAIL(dyn, ninst, scratch) \
+ if (dyn->e.stack == -8) { \
+ *ok = 0; \
+ break; \
+ } \
+ x87_do_pop(dyn, ninst, scratch);
+
+
#ifndef MAYSETFLAGS
#define MAYSETFLAGS()
#endif
#ifndef READFLAGS
-#define READFLAGS(A) \
- if(((A)!=X_PEND && dyn->f.pending!=SF_SET) \
- && (dyn->f.pending!=SF_SET_PENDING)) { \
- if(dyn->f.pending!=SF_PENDING) { \
- LD(x3, xEmu, offsetof(x64emu_t, df)); \
- j64 = (GETMARKF)-(dyn->native_size); \
- BEQ(x3, xZR, j64); \
- } \
- CALL_(UpdateFlags, -1, 0); \
- FLAGS_ADJUST_FROM11(xFlags, x3); \
- MARKF; \
- dyn->f.pending = SF_SET; \
- SET_DFOK(); \
+#define READFLAGS(A) \
+ if (((A) != X_PEND && dyn->f.pending != SF_SET) \
+ && (dyn->f.pending != SF_SET_PENDING)) { \
+ if (dyn->f.pending != SF_PENDING) { \
+ LD(x3, xEmu, offsetof(x64emu_t, df)); \
+ j64 = (GETMARKF) - (dyn->native_size); \
+ BEQ(x3, xZR, j64); \
+ } \
+ CALL_(UpdateFlags, -1, 0); \
+ FLAGS_ADJUST_FROM11(xFlags, x3); \
+ MARKF; \
+ dyn->f.pending = SF_SET; \
+ SET_DFOK(); \
}
#endif
#ifndef SETFLAGS
-#define SETFLAGS(A, B) \
- if(dyn->f.pending!=SF_SET \
- && ((B)&SF_SUB) \
- && (dyn->insts[ninst].x64.gen_flags&(~(A)))) \
- READFLAGS(((dyn->insts[ninst].x64.gen_flags&X_PEND)?X_ALL:dyn->insts[ninst].x64.gen_flags)&(~(A)));\
- if(dyn->insts[ninst].x64.gen_flags) switch(B) { \
- case SF_SUBSET: \
- case SF_SET: dyn->f.pending = SF_SET; break; \
- case SF_PENDING: dyn->f.pending = SF_PENDING; break; \
- case SF_SUBSET_PENDING: \
- case SF_SET_PENDING: \
- dyn->f.pending = (dyn->insts[ninst].x64.gen_flags&X_PEND)?SF_SET_PENDING:SF_SET; \
- break; \
- } else dyn->f.pending = SF_SET
+#define SETFLAGS(A, B) \
+ if (dyn->f.pending != SF_SET \
+ && ((B)&SF_SUB) \
+ && (dyn->insts[ninst].x64.gen_flags & (~(A)))) \
+ READFLAGS(((dyn->insts[ninst].x64.gen_flags & X_PEND) ? X_ALL : dyn->insts[ninst].x64.gen_flags) & (~(A))); \
+ if (dyn->insts[ninst].x64.gen_flags) switch (B) { \
+ case SF_SUBSET: \
+ case SF_SET: dyn->f.pending = SF_SET; break; \
+ case SF_PENDING: dyn->f.pending = SF_PENDING; break; \
+ case SF_SUBSET_PENDING: \
+ case SF_SET_PENDING: \
+ dyn->f.pending = (dyn->insts[ninst].x64.gen_flags & X_PEND) ? SF_SET_PENDING : SF_SET; \
+ break; \
+ } \
+ else \
+ dyn->f.pending = SF_SET
#endif
#ifndef JUMP
#define JUMP(A, C)
@@ -756,14 +950,27 @@
#ifndef BARRIER_NEXT
#define BARRIER_NEXT(A)
#endif
-#define UFLAG_OP1(A) if(dyn->insts[ninst].x64.gen_flags) {SDxw(A, xEmu, offsetof(x64emu_t, op1));}
-#define UFLAG_OP2(A) if(dyn->insts[ninst].x64.gen_flags) {SDxw(A, xEmu, offsetof(x64emu_t, op2));}
-#define UFLAG_OP12(A1, A2) if(dyn->insts[ninst].x64.gen_flags) {SDxw(A1, xEmu, offsetof(x64emu_t, op1));SDxw(A2, xEmu, offsetof(x64emu_t, op2));}
-#define UFLAG_RES(A) if(dyn->insts[ninst].x64.gen_flags) {SDxw(A, xEmu, offsetof(x64emu_t, res));}
-#define UFLAG_DF(r, A) if(dyn->insts[ninst].x64.gen_flags) {SET_DF(r, A)}
-#define UFLAG_IF if(dyn->insts[ninst].x64.gen_flags)
+#ifndef SET_HASCALLRET
+#define SET_HASCALLRET()
+#endif
+#define UFLAG_OP1(A) \
+ if (dyn->insts[ninst].x64.gen_flags) { SDxw(A, xEmu, offsetof(x64emu_t, op1)); }
+#define UFLAG_OP2(A) \
+ if (dyn->insts[ninst].x64.gen_flags) { SDxw(A, xEmu, offsetof(x64emu_t, op2)); }
+#define UFLAG_OP12(A1, A2) \
+ if (dyn->insts[ninst].x64.gen_flags) { \
+ SDxw(A1, xEmu, offsetof(x64emu_t, op1)); \
+ SDxw(A2, xEmu, offsetof(x64emu_t, op2)); \
+ }
+#define UFLAG_RES(A) \
+ if (dyn->insts[ninst].x64.gen_flags) { SDxw(A, xEmu, offsetof(x64emu_t, res)); }
+#define UFLAG_DF(r, A) \
+ if (dyn->insts[ninst].x64.gen_flags) { SET_DF(r, A) }
+#define UFLAG_IF if (dyn->insts[ninst].x64.gen_flags)
#ifndef DEFAULT
-#define DEFAULT *ok = -1; BARRIER(2)
+#define DEFAULT \
+ *ok = -1; \
+ BARRIER(2)
#endif
#ifndef TABLE64
@@ -781,206 +988,211 @@
#define GETIP_(A)
#else
// put value in the Table64 even if not using it for now to avoid difference between Step2 and Step3. Needs to be optimized later...
-#define GETIP(A) \
- if(dyn->last_ip && ((A)-dyn->last_ip)<2048) { \
- uint64_t _delta_ip = (A)-dyn->last_ip; \
- dyn->last_ip += _delta_ip; \
- if(_delta_ip) { \
- ADDI(xRIP, xRIP, _delta_ip); \
- } \
- } else { \
- dyn->last_ip = (A); \
- if(dyn->last_ip<0xffffffff) { \
- MOV64x(xRIP, dyn->last_ip); \
- } else \
- TABLE64(xRIP, dyn->last_ip); \
+#define GETIP(A) \
+ if (dyn->last_ip && ((A)-dyn->last_ip) < 2048) { \
+ uint64_t _delta_ip = (A)-dyn->last_ip; \
+ dyn->last_ip += _delta_ip; \
+ if (_delta_ip) { \
+ ADDI(xRIP, xRIP, _delta_ip); \
+ } \
+ } else { \
+ dyn->last_ip = (A); \
+ if (dyn->last_ip < 0xffffffff) { \
+ MOV64x(xRIP, dyn->last_ip); \
+ } else \
+ TABLE64(xRIP, dyn->last_ip); \
}
#define GETIP_(A) \
- if(dyn->last_ip && ((A)-dyn->last_ip)<2048) { \
+ if (dyn->last_ip && ((A)-dyn->last_ip) < 2048) { \
int64_t _delta_ip = (A)-dyn->last_ip; \
- if(_delta_ip) {ADDI(xRIP, xRIP, _delta_ip);} \
+ if (_delta_ip) { ADDI(xRIP, xRIP, _delta_ip); } \
} else { \
- if((A)<0xffffffff) { \
+ if ((A) < 0xffffffff) { \
MOV64x(xRIP, (A)); \
} else \
TABLE64(xRIP, (A)); \
}
#endif
-#define CLEARIP() dyn->last_ip=0
+#define CLEARIP() dyn->last_ip = 0
#if STEP < 2
-#define PASS2IF(A, B) if(A)
+#define PASS2IF(A, B) if (A)
#elif STEP == 2
-#define PASS2IF(A, B) if(A) dyn->insts[ninst].pass2choice = B; if(dyn->insts[ninst].pass2choice == B)
+#define PASS2IF(A, B) \
+ if (A) dyn->insts[ninst].pass2choice = B; \
+ if (dyn->insts[ninst].pass2choice == B)
#else
-#define PASS2IF(A, B) if(dyn->insts[ninst].pass2choice == B)
+#define PASS2IF(A, B) if (dyn->insts[ninst].pass2choice == B)
#endif
-#define MODREG ((nextop&0xC0)==0xC0)
+#define MODREG ((nextop & 0xC0) == 0xC0)
void rv64_epilog(void);
void rv64_epilog_fast(void);
void* rv64_next(x64emu_t* emu, uintptr_t addr);
#ifndef STEPNAME
-#define STEPNAME3(N,M) N##M
-#define STEPNAME2(N,M) STEPNAME3(N,M)
-#define STEPNAME(N) STEPNAME2(N, STEP)
+#define STEPNAME3(N, M) N##M
+#define STEPNAME2(N, M) STEPNAME3(N, M)
+#define STEPNAME(N) STEPNAME2(N, STEP)
#endif
-#define native_pass STEPNAME(native_pass)
-
-#define dynarec64_00 STEPNAME(dynarec64_00)
-#define dynarec64_00_0 STEPNAME(dynarec64_00_0)
-#define dynarec64_00_1 STEPNAME(dynarec64_00_1)
-#define dynarec64_00_2 STEPNAME(dynarec64_00_2)
-#define dynarec64_00_3 STEPNAME(dynarec64_00_3)
-#define dynarec64_0F STEPNAME(dynarec64_0F)
-#define dynarec64_64 STEPNAME(dynarec64_64)
-#define dynarec64_65 STEPNAME(dynarec64_65)
-#define dynarec64_66 STEPNAME(dynarec64_66)
-#define dynarec64_67 STEPNAME(dynarec64_67)
-#define dynarec64_D8 STEPNAME(dynarec64_D8)
-#define dynarec64_D9 STEPNAME(dynarec64_D9)
-#define dynarec64_DA STEPNAME(dynarec64_DA)
-#define dynarec64_DB STEPNAME(dynarec64_DB)
-#define dynarec64_DC STEPNAME(dynarec64_DC)
-#define dynarec64_DD STEPNAME(dynarec64_DD)
-#define dynarec64_DE STEPNAME(dynarec64_DE)
-#define dynarec64_DF STEPNAME(dynarec64_DF)
-#define dynarec64_F0 STEPNAME(dynarec64_F0)
-#define dynarec64_660F STEPNAME(dynarec64_660F)
-#define dynarec64_6664 STEPNAME(dynarec64_6664)
-#define dynarec64_66F0 STEPNAME(dynarec64_66F0)
-#define dynarec64_F20F STEPNAME(dynarec64_F20F)
-#define dynarec64_F30F STEPNAME(dynarec64_F30F)
-
-#define geted STEPNAME(geted)
-#define geted32 STEPNAME(geted32)
-#define geted16 STEPNAME(geted16)
-#define jump_to_epilog STEPNAME(jump_to_epilog)
-#define jump_to_epilog_fast STEPNAME(jump_to_epilog_fast)
-#define jump_to_next STEPNAME(jump_to_next)
-#define ret_to_epilog STEPNAME(ret_to_epilog)
-#define retn_to_epilog STEPNAME(retn_to_epilog)
-#define iret_to_epilog STEPNAME(iret_to_epilog)
-#define call_c STEPNAME(call_c)
-#define call_n STEPNAME(call_n)
-#define grab_segdata STEPNAME(grab_segdata)
-#define emit_cmp8 STEPNAME(emit_cmp8)
-#define emit_cmp16 STEPNAME(emit_cmp16)
-#define emit_cmp32 STEPNAME(emit_cmp32)
-#define emit_cmp8_0 STEPNAME(emit_cmp8_0)
-#define emit_cmp16_0 STEPNAME(emit_cmp16_0)
-#define emit_cmp32_0 STEPNAME(emit_cmp32_0)
-#define emit_test8 STEPNAME(emit_test8)
-#define emit_test16 STEPNAME(emit_test16)
-#define emit_test32 STEPNAME(emit_test32)
-#define emit_test32c STEPNAME(emit_test32)
-#define emit_add32 STEPNAME(emit_add32)
-#define emit_add32c STEPNAME(emit_add32c)
-#define emit_add8 STEPNAME(emit_add8)
-#define emit_add8c STEPNAME(emit_add8c)
-#define emit_sub32 STEPNAME(emit_sub32)
-#define emit_sub32c STEPNAME(emit_sub32c)
-#define emit_sub8 STEPNAME(emit_sub8)
-#define emit_sub8c STEPNAME(emit_sub8c)
-#define emit_or32 STEPNAME(emit_or32)
-#define emit_or32c STEPNAME(emit_or32c)
-#define emit_xor32 STEPNAME(emit_xor32)
-#define emit_xor32c STEPNAME(emit_xor32c)
-#define emit_and32 STEPNAME(emit_and32)
-#define emit_and32c STEPNAME(emit_and32c)
-#define emit_or8 STEPNAME(emit_or8)
-#define emit_or8c STEPNAME(emit_or8c)
-#define emit_xor8 STEPNAME(emit_xor8)
-#define emit_xor8c STEPNAME(emit_xor8c)
-#define emit_and8 STEPNAME(emit_and8)
-#define emit_and8c STEPNAME(emit_and8c)
-#define emit_add16 STEPNAME(emit_add16)
-#define emit_add16c STEPNAME(emit_add16c)
-#define emit_sub16 STEPNAME(emit_sub16)
-#define emit_sub16c STEPNAME(emit_sub16c)
-#define emit_or16 STEPNAME(emit_or16)
-#define emit_or16c STEPNAME(emit_or16c)
-#define emit_xor16 STEPNAME(emit_xor16)
-#define emit_xor16c STEPNAME(emit_xor16c)
-#define emit_and16 STEPNAME(emit_and16)
-#define emit_and16c STEPNAME(emit_and16c)
-#define emit_inc32 STEPNAME(emit_inc32)
-#define emit_inc16 STEPNAME(emit_inc16)
-#define emit_inc8 STEPNAME(emit_inc8)
-#define emit_dec32 STEPNAME(emit_dec32)
-#define emit_dec16 STEPNAME(emit_dec16)
-#define emit_dec8 STEPNAME(emit_dec8)
-#define emit_adc32 STEPNAME(emit_adc32)
-#define emit_adc32c STEPNAME(emit_adc32c)
-#define emit_adc8 STEPNAME(emit_adc8)
-#define emit_adc8c STEPNAME(emit_adc8c)
-#define emit_adc16 STEPNAME(emit_adc16)
-#define emit_adc16c STEPNAME(emit_adc16c)
-#define emit_sbb32 STEPNAME(emit_sbb32)
-#define emit_sbb32c STEPNAME(emit_sbb32c)
-#define emit_sbb8 STEPNAME(emit_sbb8)
-#define emit_sbb8c STEPNAME(emit_sbb8c)
-#define emit_sbb16 STEPNAME(emit_sbb16)
-#define emit_sbb16c STEPNAME(emit_sbb16c)
-#define emit_neg32 STEPNAME(emit_neg32)
-#define emit_neg16 STEPNAME(emit_neg16)
-#define emit_neg8 STEPNAME(emit_neg8)
-#define emit_shl32 STEPNAME(emit_shl32)
-#define emit_shl32c STEPNAME(emit_shl32c)
-#define emit_shr32 STEPNAME(emit_shr32)
-#define emit_shr32c STEPNAME(emit_shr32c)
-#define emit_sar32c STEPNAME(emit_sar32c)
-#define emit_rol32 STEPNAME(emit_rol32)
-#define emit_ror32 STEPNAME(emit_ror32)
-#define emit_rol32c STEPNAME(emit_rol32c)
-#define emit_ror32c STEPNAME(emit_ror32c)
-#define emit_shrd32c STEPNAME(emit_shrd32c)
-#define emit_shld32c STEPNAME(emit_shld32c)
-
-#define emit_pf STEPNAME(emit_pf)
-
-#define x87_do_push STEPNAME(x87_do_push)
-#define x87_do_push_empty STEPNAME(x87_do_push_empty)
-#define x87_do_pop STEPNAME(x87_do_pop)
-#define x87_get_current_cache STEPNAME(x87_get_current_cache)
-#define x87_get_cache STEPNAME(x87_get_cache)
-#define x87_get_extcache STEPNAME(x87_get_extcache)
-#define x87_get_st STEPNAME(x87_get_st)
-#define x87_get_st_empty STEPNAME(x87_get_st)
-#define x87_refresh STEPNAME(x87_refresh)
-#define x87_forget STEPNAME(x87_forget)
-#define x87_reget_st STEPNAME(x87_reget_st)
-#define x87_stackcount STEPNAME(x87_stackcount)
-#define x87_swapreg STEPNAME(x87_swapreg)
-#define x87_setround STEPNAME(x87_setround)
-#define x87_restoreround STEPNAME(x87_restoreround)
-#define sse_setround STEPNAME(sse_setround)
-#define mmx_get_reg STEPNAME(mmx_get_reg)
-#define mmx_get_reg_empty STEPNAME(mmx_get_reg_empty)
-#define mmx_forget_reg STEPNAME(mmx_forget_reg)
-#define sse_get_reg STEPNAME(sse_get_reg)
-#define sse_get_reg_empty STEPNAME(sse_get_reg_empty)
-#define sse_forget_reg STEPNAME(sse_forget_reg)
-#define sse_purge07cache STEPNAME(sse_purge07cache)
-
-#define fpu_pushcache STEPNAME(fpu_pushcache)
-#define fpu_popcache STEPNAME(fpu_popcache)
-#define fpu_reset STEPNAME(fpu_reset)
-#define fpu_reset_cache STEPNAME(fpu_reset_cache)
+#define native_pass STEPNAME(native_pass)
+
+#define dynarec64_00 STEPNAME(dynarec64_00)
+#define dynarec64_00_0 STEPNAME(dynarec64_00_0)
+#define dynarec64_00_1 STEPNAME(dynarec64_00_1)
+#define dynarec64_00_2 STEPNAME(dynarec64_00_2)
+#define dynarec64_00_3 STEPNAME(dynarec64_00_3)
+#define dynarec64_0F STEPNAME(dynarec64_0F)
+#define dynarec64_64 STEPNAME(dynarec64_64)
+#define dynarec64_65 STEPNAME(dynarec64_65)
+#define dynarec64_66 STEPNAME(dynarec64_66)
+#define dynarec64_67 STEPNAME(dynarec64_67)
+#define dynarec64_67_32 STEPNAME(dynarec64_67_32)
+#define dynarec64_D8 STEPNAME(dynarec64_D8)
+#define dynarec64_D9 STEPNAME(dynarec64_D9)
+#define dynarec64_DA STEPNAME(dynarec64_DA)
+#define dynarec64_DB STEPNAME(dynarec64_DB)
+#define dynarec64_DC STEPNAME(dynarec64_DC)
+#define dynarec64_DD STEPNAME(dynarec64_DD)
+#define dynarec64_DE STEPNAME(dynarec64_DE)
+#define dynarec64_DF STEPNAME(dynarec64_DF)
+#define dynarec64_F0 STEPNAME(dynarec64_F0)
+#define dynarec64_660F STEPNAME(dynarec64_660F)
+#define dynarec64_66F20F STEPNAME(dynarec64_66F20F)
+#define dynarec64_66F30F STEPNAME(dynarec64_66F30F)
+#define dynarec64_6664 STEPNAME(dynarec64_6664)
+#define dynarec64_66F0 STEPNAME(dynarec64_66F0)
+#define dynarec64_F20F STEPNAME(dynarec64_F20F)
+#define dynarec64_F30F STEPNAME(dynarec64_F30F)
+
+#define geted STEPNAME(geted)
+#define geted32 STEPNAME(geted32)
+#define geted16 STEPNAME(geted16)
+#define jump_to_epilog STEPNAME(jump_to_epilog)
+#define jump_to_epilog_fast STEPNAME(jump_to_epilog_fast)
+#define jump_to_next STEPNAME(jump_to_next)
+#define ret_to_epilog STEPNAME(ret_to_epilog)
+#define retn_to_epilog STEPNAME(retn_to_epilog)
+#define iret_to_epilog STEPNAME(iret_to_epilog)
+#define call_c STEPNAME(call_c)
+#define call_n STEPNAME(call_n)
+#define grab_segdata STEPNAME(grab_segdata)
+#define emit_cmp8 STEPNAME(emit_cmp8)
+#define emit_cmp16 STEPNAME(emit_cmp16)
+#define emit_cmp32 STEPNAME(emit_cmp32)
+#define emit_cmp8_0 STEPNAME(emit_cmp8_0)
+#define emit_cmp16_0 STEPNAME(emit_cmp16_0)
+#define emit_cmp32_0 STEPNAME(emit_cmp32_0)
+#define emit_test8 STEPNAME(emit_test8)
+#define emit_test16 STEPNAME(emit_test16)
+#define emit_test32 STEPNAME(emit_test32)
+#define emit_test32c STEPNAME(emit_test32)
+#define emit_add32 STEPNAME(emit_add32)
+#define emit_add32c STEPNAME(emit_add32c)
+#define emit_add8 STEPNAME(emit_add8)
+#define emit_add8c STEPNAME(emit_add8c)
+#define emit_sub32 STEPNAME(emit_sub32)
+#define emit_sub32c STEPNAME(emit_sub32c)
+#define emit_sub8 STEPNAME(emit_sub8)
+#define emit_sub8c STEPNAME(emit_sub8c)
+#define emit_or32 STEPNAME(emit_or32)
+#define emit_or32c STEPNAME(emit_or32c)
+#define emit_xor32 STEPNAME(emit_xor32)
+#define emit_xor32c STEPNAME(emit_xor32c)
+#define emit_and32 STEPNAME(emit_and32)
+#define emit_and32c STEPNAME(emit_and32c)
+#define emit_or8 STEPNAME(emit_or8)
+#define emit_or8c STEPNAME(emit_or8c)
+#define emit_xor8 STEPNAME(emit_xor8)
+#define emit_xor8c STEPNAME(emit_xor8c)
+#define emit_and8 STEPNAME(emit_and8)
+#define emit_and8c STEPNAME(emit_and8c)
+#define emit_add16 STEPNAME(emit_add16)
+#define emit_add16c STEPNAME(emit_add16c)
+#define emit_sub16 STEPNAME(emit_sub16)
+#define emit_sub16c STEPNAME(emit_sub16c)
+#define emit_or16 STEPNAME(emit_or16)
+#define emit_or16c STEPNAME(emit_or16c)
+#define emit_xor16 STEPNAME(emit_xor16)
+#define emit_xor16c STEPNAME(emit_xor16c)
+#define emit_and16 STEPNAME(emit_and16)
+#define emit_and16c STEPNAME(emit_and16c)
+#define emit_inc32 STEPNAME(emit_inc32)
+#define emit_inc16 STEPNAME(emit_inc16)
+#define emit_inc8 STEPNAME(emit_inc8)
+#define emit_dec32 STEPNAME(emit_dec32)
+#define emit_dec16 STEPNAME(emit_dec16)
+#define emit_dec8 STEPNAME(emit_dec8)
+#define emit_adc32 STEPNAME(emit_adc32)
+#define emit_adc32c STEPNAME(emit_adc32c)
+#define emit_adc8 STEPNAME(emit_adc8)
+#define emit_adc8c STEPNAME(emit_adc8c)
+#define emit_adc16 STEPNAME(emit_adc16)
+#define emit_adc16c STEPNAME(emit_adc16c)
+#define emit_sbb32 STEPNAME(emit_sbb32)
+#define emit_sbb32c STEPNAME(emit_sbb32c)
+#define emit_sbb8 STEPNAME(emit_sbb8)
+#define emit_sbb8c STEPNAME(emit_sbb8c)
+#define emit_sbb16 STEPNAME(emit_sbb16)
+#define emit_sbb16c STEPNAME(emit_sbb16c)
+#define emit_neg32 STEPNAME(emit_neg32)
+#define emit_neg16 STEPNAME(emit_neg16)
+#define emit_neg8 STEPNAME(emit_neg8)
+#define emit_shl32 STEPNAME(emit_shl32)
+#define emit_shl32c STEPNAME(emit_shl32c)
+#define emit_shr32 STEPNAME(emit_shr32)
+#define emit_shr32c STEPNAME(emit_shr32c)
+#define emit_sar32c STEPNAME(emit_sar32c)
+#define emit_rol32 STEPNAME(emit_rol32)
+#define emit_ror32 STEPNAME(emit_ror32)
+#define emit_rol32c STEPNAME(emit_rol32c)
+#define emit_ror32c STEPNAME(emit_ror32c)
+#define emit_shrd32c STEPNAME(emit_shrd32c)
+#define emit_shld32c STEPNAME(emit_shld32c)
+
+#define emit_pf STEPNAME(emit_pf)
+
+#define x87_do_push STEPNAME(x87_do_push)
+#define x87_do_push_empty STEPNAME(x87_do_push_empty)
+#define x87_do_pop STEPNAME(x87_do_pop)
+#define x87_get_current_cache STEPNAME(x87_get_current_cache)
+#define x87_get_cache STEPNAME(x87_get_cache)
+#define x87_get_extcache STEPNAME(x87_get_extcache)
+#define x87_get_st STEPNAME(x87_get_st)
+#define x87_get_st_empty STEPNAME(x87_get_st)
+#define x87_refresh STEPNAME(x87_refresh)
+#define x87_forget STEPNAME(x87_forget)
+#define x87_reget_st STEPNAME(x87_reget_st)
+#define x87_stackcount STEPNAME(x87_stackcount)
+#define x87_swapreg STEPNAME(x87_swapreg)
+#define x87_setround STEPNAME(x87_setround)
+#define x87_restoreround STEPNAME(x87_restoreround)
+#define sse_setround STEPNAME(sse_setround)
+#define mmx_get_reg STEPNAME(mmx_get_reg)
+#define mmx_get_reg_empty STEPNAME(mmx_get_reg_empty)
+#define mmx_forget_reg STEPNAME(mmx_forget_reg)
+#define sse_get_reg STEPNAME(sse_get_reg)
+#define sse_get_reg_empty STEPNAME(sse_get_reg_empty)
+#define sse_forget_reg STEPNAME(sse_forget_reg)
+#define sse_purge07cache STEPNAME(sse_purge07cache)
+
+#define fpu_pushcache STEPNAME(fpu_pushcache)
+#define fpu_popcache STEPNAME(fpu_popcache)
+#define fpu_reset STEPNAME(fpu_reset)
+#define fpu_reset_cache STEPNAME(fpu_reset_cache)
#define fpu_propagate_stack STEPNAME(fpu_propagate_stack)
-#define fpu_purgecache STEPNAME(fpu_purgecache)
-#define mmx_purgecache STEPNAME(mmx_purgecache)
-#define x87_purgecache STEPNAME(x87_purgecache)
-#define sse_purgecache STEPNAME(sse_purgecache)
-#define fpu_reflectcache STEPNAME(fpu_reflectcache)
-#define fpu_unreflectcache STEPNAME(fpu_unreflectcache)
+#define fpu_purgecache STEPNAME(fpu_purgecache)
+#define mmx_purgecache STEPNAME(mmx_purgecache)
+#define x87_purgecache STEPNAME(x87_purgecache)
+#define sse_purgecache STEPNAME(sse_purgecache)
+#define fpu_reflectcache STEPNAME(fpu_reflectcache)
+#define fpu_unreflectcache STEPNAME(fpu_unreflectcache)
-#define CacheTransform STEPNAME(CacheTransform)
-#define rv64_move64 STEPNAME(rv64_move64)
-#define rv64_move32 STEPNAME(rv64_move32)
+#define CacheTransform STEPNAME(CacheTransform)
+#define rv64_move64 STEPNAME(rv64_move64)
+#define rv64_move32 STEPNAME(rv64_move32)
/* setup r2 to address pointed by */
uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta);
@@ -989,7 +1201,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
uintptr_t geted32(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, rex_t rex, int* l, int i12, int delta);
/* setup r2 to address pointed by */
-//uintptr_t geted16(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int64_t* fixaddress, int absmax, uint32_t mask, int s);
+// uintptr_t geted16(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int64_t* fixaddress, int absmax, uint32_t mask, int s);
// generic x64 helper
@@ -1033,15 +1245,15 @@ void emit_xor8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s
void emit_and8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_add16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
-//void emit_add16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_add16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_sub16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
-//void emit_sub16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_sub16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_or16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
-//void emit_or16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_or16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_xor16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
-//void emit_xor16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_xor16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_and16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
-//void emit_and16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_and16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_inc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5);
void emit_inc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
void emit_inc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
@@ -1049,17 +1261,17 @@ void emit_dec32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
void emit_dec16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
void emit_dec8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5, int s6);
-//void emit_adc32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_adc32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
void emit_adc8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5, int s6);
void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
-//void emit_adc16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_adc16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5);
-//void emit_sbb32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_sbb32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
void emit_sbb8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5, int s6);
void emit_sbb16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
-//void emit_sbb16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+// void emit_sbb16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
void emit_neg32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3);
void emit_neg16(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4);
void emit_neg8(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4);
@@ -1117,44 +1329,44 @@ void rv64_move64(dynarec_rv64_t* dyn, int ninst, int reg, int64_t val);
void rv64_move32(dynarec_rv64_t* dyn, int ninst, int reg, int32_t val, int zeroup);
#if STEP < 2
-#define CHECK_CACHE() 0
+#define CHECK_CACHE() 0
#else
-#define CHECK_CACHE() (cacheupd = CacheNeedsTransform(dyn, ninst))
+#define CHECK_CACHE() (cacheupd = CacheNeedsTransform(dyn, ninst))
#endif
#define extcache_st_coherency STEPNAME(extcache_st_coherency)
int extcache_st_coherency(dynarec_rv64_t* dyn, int ninst, int a, int b);
#if STEP == 0
-#define ST_IS_F(A) 0
-#define X87_COMBINE(A, B) EXT_CACHE_ST_D
-#define X87_ST0 EXT_CACHE_ST_D
-#define X87_ST(A) EXT_CACHE_ST_D
+#define ST_IS_F(A) 0
+#define X87_COMBINE(A, B) EXT_CACHE_ST_D
+#define X87_ST0 EXT_CACHE_ST_D
+#define X87_ST(A) EXT_CACHE_ST_D
#elif STEP == 1
-#define ST_IS_F(A) (extcache_get_current_st(dyn, ninst, A)==EXT_CACHE_ST_F)
+#define ST_IS_F(A) (extcache_get_current_st(dyn, ninst, A) == EXT_CACHE_ST_F)
#define X87_COMBINE(A, B) extcache_combine_st(dyn, ninst, A, B)
-#define X87_ST0 extcache_get_current_st(dyn, ninst, 0)
-#define X87_ST(A) extcache_get_current_st(dyn, ninst, A)
+#define X87_ST0 extcache_get_current_st(dyn, ninst, 0)
+#define X87_ST(A) extcache_get_current_st(dyn, ninst, A)
#else
-#define ST_IS_F(A) (extcache_get_st(dyn, ninst, A)==EXT_CACHE_ST_F)
+#define ST_IS_F(A) (extcache_get_st(dyn, ninst, A) == EXT_CACHE_ST_F)
#if STEP == 3
#define X87_COMBINE(A, B) extcache_st_coherency(dyn, ninst, A, B)
#else
#define X87_COMBINE(A, B) extcache_get_st(dyn, ninst, A)
#endif
-#define X87_ST0 extcache_get_st(dyn, ninst, 0)
-#define X87_ST(A) extcache_get_st(dyn, ninst, A)
+#define X87_ST0 extcache_get_st(dyn, ninst, 0)
+#define X87_ST(A) extcache_get_st(dyn, ninst, A)
#endif
-//MMX helpers
-// get float register for a MMX reg, create the entry if needed
+// MMX helpers
+// get float register for a MMX reg, create the entry if needed
int mmx_get_reg(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int a);
// get float register for a MMX reg, but don't try to synch it if it needed to be created
int mmx_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int a);
// forget float register for a MMX reg, create the entry if needed
void mmx_forget_reg(dynarec_rv64_t* dyn, int ninst, int a);
-//SSE/SSE2 helpers
-// get float register for a SSE reg, create the entry if needed
+// SSE/SSE2 helpers
+// get float register for a SSE reg, create the entry if needed
int sse_get_reg(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single);
// get float register for a SSE reg, but don't try to synch it if it needed to be created
int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single);
@@ -1189,12 +1401,13 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog);
-//uintptr_t dynarec64_65(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
+// uintptr_t dynarec64_65(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_67_32(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-//uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
@@ -1202,6 +1415,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_66F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_66F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog);
uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
@@ -1210,139 +1425,150 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
#if STEP < 2
#define PASS2(A)
#else
-#define PASS2(A) A
+#define PASS2(A) A
#endif
#if STEP < 3
#define PASS3(A)
#else
-#define PASS3(A) A
+#define PASS3(A) A
#endif
#if STEP < 3
-#define MAYUSE(A) (void)A
+#define MAYUSE(A) (void)A
#else
#define MAYUSE(A)
#endif
// GOCOND will use x1 and x3
-#define GOCOND(B, T1, T2) \
- case B+0x0: \
- INST_NAME(T1 "O " T2); \
- GO( ANDI(x1, xFlags, 1<<F_OF2) \
- , EQZ, NEZ, X_OF) \
- break; \
- case B+0x1: \
- INST_NAME(T1 "NO " T2); \
- GO( ANDI(x1, xFlags, 1<<F_OF2) \
- , NEZ, EQZ, X_OF) \
- break; \
- case B+0x2: \
- INST_NAME(T1 "C " T2); \
- GO( ANDI(x1, xFlags, 1<<F_CF) \
- , EQZ, NEZ, X_CF) \
- break; \
- case B+0x3: \
- INST_NAME(T1 "NC " T2); \
- GO( ANDI(x1, xFlags, 1<<F_CF) \
- , NEZ, EQZ, X_CF) \
- break; \
- case B+0x4: \
- INST_NAME(T1 "Z " T2); \
- GO( ANDI(x1, xFlags, 1<<F_ZF) \
- , EQZ, NEZ, X_ZF) \
- break; \
- case B+0x5: \
- INST_NAME(T1 "NZ " T2); \
- GO( ANDI(x1, xFlags, 1<<F_ZF) \
- , NEZ, EQZ, X_ZF) \
- break; \
- case B+0x6: \
- INST_NAME(T1 "BE " T2); \
- GO( ANDI(x1, xFlags, (1<<F_CF)|(1<<F_ZF)) \
- , EQZ, NEZ, X_CF|X_ZF) \
- break; \
- case B+0x7: \
- INST_NAME(T1 "NBE " T2); \
- GO( ANDI(x1, xFlags, (1<<F_CF)|(1<<F_ZF)) \
- , NEZ, EQZ, X_CF|X_ZF) \
- break; \
- case B+0x8: \
- INST_NAME(T1 "S " T2); \
- GO( ANDI(x1, xFlags, 1<<F_SF) \
- , EQZ, NEZ, X_SF) \
- break; \
- case B+0x9: \
- INST_NAME(T1 "NS " T2); \
- GO( ANDI(x1, xFlags, 1<<F_SF) \
- , NEZ, EQZ, X_SF) \
- break; \
- case B+0xA: \
- INST_NAME(T1 "P " T2); \
- GO( ANDI(x1, xFlags, 1<<F_PF) \
- , EQZ, NEZ, X_PF) \
- break; \
- case B+0xB: \
- INST_NAME(T1 "NP " T2); \
- GO( ANDI(x1, xFlags, 1<<F_PF) \
- , NEZ, EQZ, X_PF) \
- break; \
- case B+0xC: \
- INST_NAME(T1 "L " T2); \
- GO( SRLI(x1, xFlags, F_SF-F_OF2); \
- XOR(x1, x1, xFlags); \
- ANDI(x1, x1, 1<<F_OF2) \
- , EQZ, NEZ, X_SF|X_OF) \
- break; \
- case B+0xD: \
- INST_NAME(T1 "GE " T2); \
- GO( SRLI(x1, xFlags, F_SF-F_OF2); \
- XOR(x1, x1, xFlags); \
- ANDI(x1, x1, 1<<F_OF2) \
- , NEZ, EQZ, X_SF|X_OF) \
- break; \
- case B+0xE: \
- INST_NAME(T1 "LE " T2); \
- GO( SRLI(x1, xFlags, F_SF-F_OF2); \
- XOR(x1, x1, xFlags); \
- ANDI(x1, x1, 1<<F_OF2); \
- ANDI(x3, xFlags, 1<<F_ZF); \
- OR(x1, x1, x3); \
- ANDI(x1, x1, (1<<F_OF2) | (1<<F_ZF)) \
- , EQZ, NEZ, X_SF|X_OF|X_ZF) \
- break; \
- case B+0xF: \
- INST_NAME(T1 "G " T2); \
- GO( SRLI(x1, xFlags, F_SF-F_OF2); \
- XOR(x1, x1, xFlags); \
- ANDI(x1, x1, 1<<F_OF2); \
- ANDI(x3, xFlags, 1<<F_ZF); \
- OR(x1, x1, x3); \
- ANDI(x1, x1, (1<<F_OF2) | (1<<F_ZF)) \
- , NEZ, EQZ, X_SF|X_OF|X_ZF) \
+#define GOCOND(B, T1, T2) \
+ case B + 0x0: \
+ INST_NAME(T1 "O " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_OF2), EQZ, NEZ, X_OF) \
+ break; \
+ case B + 0x1: \
+ INST_NAME(T1 "NO " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_OF2), NEZ, EQZ, X_OF) \
+ break; \
+ case B + 0x2: \
+ INST_NAME(T1 "C " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_CF), EQZ, NEZ, X_CF) \
+ break; \
+ case B + 0x3: \
+ INST_NAME(T1 "NC " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_CF), NEZ, EQZ, X_CF) \
+ break; \
+ case B + 0x4: \
+ INST_NAME(T1 "Z " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_ZF), EQZ, NEZ, X_ZF) \
+ break; \
+ case B + 0x5: \
+ INST_NAME(T1 "NZ " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_ZF), NEZ, EQZ, X_ZF) \
+ break; \
+ case B + 0x6: \
+ INST_NAME(T1 "BE " T2); \
+ GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), EQZ, NEZ, X_CF | X_ZF) \
+ break; \
+ case B + 0x7: \
+ INST_NAME(T1 "NBE " T2); \
+ GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), NEZ, EQZ, X_CF | X_ZF) \
+ break; \
+ case B + 0x8: \
+ INST_NAME(T1 "S " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_SF), EQZ, NEZ, X_SF) \
+ break; \
+ case B + 0x9: \
+ INST_NAME(T1 "NS " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_SF), NEZ, EQZ, X_SF) \
+ break; \
+ case B + 0xA: \
+ INST_NAME(T1 "P " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_PF), EQZ, NEZ, X_PF) \
+ break; \
+ case B + 0xB: \
+ INST_NAME(T1 "NP " T2); \
+ GO(ANDI(x1, xFlags, 1 << F_PF), NEZ, EQZ, X_PF) \
+ break; \
+ case B + 0xC: \
+ INST_NAME(T1 "L " T2); \
+ GO(SRLI(x1, xFlags, F_SF - F_OF2); \
+ XOR(x1, x1, xFlags); \
+ ANDI(x1, x1, 1 << F_OF2), EQZ, NEZ, X_SF | X_OF) \
+ break; \
+ case B + 0xD: \
+ INST_NAME(T1 "GE " T2); \
+ GO(SRLI(x1, xFlags, F_SF - F_OF2); \
+ XOR(x1, x1, xFlags); \
+ ANDI(x1, x1, 1 << F_OF2), NEZ, EQZ, X_SF | X_OF) \
+ break; \
+ case B + 0xE: \
+ INST_NAME(T1 "LE " T2); \
+ GO(SRLI(x1, xFlags, F_SF - F_OF2); \
+ XOR(x1, x1, xFlags); \
+ ANDI(x1, x1, 1 << F_OF2); \
+ ANDI(x3, xFlags, 1 << F_ZF); \
+ OR(x1, x1, x3); \
+ ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), EQZ, NEZ, X_SF | X_OF | X_ZF) \
+ break; \
+ case B + 0xF: \
+ INST_NAME(T1 "G " T2); \
+ GO(SRLI(x1, xFlags, F_SF - F_OF2); \
+ XOR(x1, x1, xFlags); \
+ ANDI(x1, x1, 1 << F_OF2); \
+ ANDI(x3, xFlags, 1 << F_ZF); \
+ OR(x1, x1, x3); \
+ ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), NEZ, EQZ, X_SF | X_OF | X_ZF) \
break
-#define NOTEST(s1) \
- if(box64_dynarec_test) { \
- SW(xZR, xEmu, offsetof(x64emu_t, test.test)); \
- SW(xZR, xEmu, offsetof(x64emu_t, test.clean)); \
+#define NOTEST(s1) \
+ if (box64_dynarec_test) { \
+ SW(xZR, xEmu, offsetof(x64emu_t, test.test)); \
+ SW(xZR, xEmu, offsetof(x64emu_t, test.clean)); \
}
-#define SKIPTEST(s1) \
- if(box64_dynarec_test) { \
- SW(xZR, xEmu, offsetof(x64emu_t, test.clean)); \
+#define SKIPTEST(s1) \
+ if (box64_dynarec_test) { \
+ SW(xZR, xEmu, offsetof(x64emu_t, test.clean)); \
}
-#define GOTEST(s1, s2) \
- if(box64_dynarec_test) { \
- MOV32w(s2, 1); \
- SW(s2, xEmu, offsetof(x64emu_t, test.test)); \
+#define GOTEST(s1, s2) \
+ if (box64_dynarec_test) { \
+ MOV32w(s2, 1); \
+ SW(s2, xEmu, offsetof(x64emu_t, test.test)); \
}
-#define GETREX() \
- rex.rex = 0; \
- if(!rex.is32bits) \
- while(opcode>=0x40 && opcode<=0x4f) { \
- rex.rex = opcode; \
- opcode = F8; \
+#define GETREX() \
+ rex.rex = 0; \
+ if (!rex.is32bits) \
+ while (opcode >= 0x40 && opcode <= 0x4f) { \
+ rex.rex = opcode; \
+ opcode = F8; \
}
+
+#define FCOM(w, v1, v2, s1, s2, s3, s4, s5) \
+ LHU(s3, xEmu, offsetof(x64emu_t, sw)); \
+ MOV32w(s1, 0b1011100011111111); /* mask off c0,c1,c2,c3 */ \
+ AND(s3, s3, s1); \
+ FEQ##w(s5, v1, v1); \
+ FEQ##w(s4, v2, v2); \
+ AND(s5, s5, s4); \
+ BEQZ(s5, 24); /* undefined/NaN */ \
+ FEQ##w(s5, v1, v2); \
+ BNEZ(s5, 28); /* equal */ \
+ FLT##w(s2, v1, v2); /* x2 = (v1<v2)?1:0 */ \
+ SLLI(s1, s2, 8); \
+ J(20); /* end */ \
+ /* undefined/NaN */ \
+ LUI(s1, 4); \
+ ADDI(s1, s1, 0b010100000000); \
+ J(8); /* end */ \
+ /* equal */ \
+ LUI(s1, 4); \
+ /* end */ \
+ OR(s3, s3, s1); \
+ SH(s3, xEmu, offsetof(x64emu_t, sw));
+
+#define FCOMS(v1, v2, s1, s2, s3, s4, s5) FCOM(S, v1, v2, s1, s2, s3, s4, s5)
+#define FCOMD(v1, v2, s1, s2, s3, s4, s5) FCOM(D, v1, v2, s1, s2, s3, s4, s5)
+
#endif //__DYNAREC_RV64_HELPER_H__
diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h
index fbba8f2..89c4214 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass0.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass0.h
@@ -16,9 +16,10 @@
dyn->f.pending=(B)&SF_SET_PENDING; \
dyn->f.dfnone=((B)&SF_SET)?1:0;
#define EMIT(A)
-#define JUMP(A, C) add_next(dyn, (uintptr_t)A); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
+#define JUMP(A, C) add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C
#define BARRIER(A) if(A!=BARRIER_MAYBE) {fpu_purgecache(dyn, ninst, 0, x1, x2, x3); dyn->insts[ninst].x64.barrier = A;} else dyn->insts[ninst].barrier_maybe = 1
-#define BARRIER_NEXT(A) dyn->insts[ninst+1].x64.barrier = A
+#define BARRIER_NEXT(A) dyn->insts[ninst].x64.barrier_next = A
+#define SET_HASCALLRET() dyn->insts[ninst].x64.has_callret = 1
#define NEW_INST \
++dyn->size; \
if(dyn->size+3>=dyn->cap) { \
diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h
index 9913529..907de0a 100644
--- a/src/dynarec/rv64/dynarec_rv64_private.h
+++ b/src/dynarec/rv64/dynarec_rv64_private.h
@@ -79,8 +79,8 @@ typedef struct instruction_rv64_s {
int size2; // size of the arm emitted instrucion after pass2
int pred_sz; // size of predecessor list
int *pred; // predecessor array
- uintptr_t mark, mark2, mark3;
- uintptr_t markf, markf2;
+ uintptr_t mark[3];
+ uintptr_t markf[2];
uintptr_t markseg;
uintptr_t marklock;
int pass2choice;// value for choices that are fixed on pass2 for pass3
@@ -112,6 +112,9 @@ typedef struct dynarec_rv64_s {
uintptr_t* next; // variable array of "next" jump address
int next_sz;
int next_cap;
+ int* jmps; // variable array of jump instructions
+ int jmp_sz;
+ int jmp_cap;
int* predecessor;// single array of all predecessor
dynablock_t* dynablock;
instsize_t* instsize;
@@ -132,6 +135,8 @@ typedef struct dynarec_rv64_s {
void add_next(dynarec_rv64_t *dyn, uintptr_t addr);
uintptr_t get_closest_next(dynarec_rv64_t *dyn, uintptr_t addr);
+void add_jump(dynarec_rv64_t *dyn, int ninst);
+int get_first_jump(dynarec_rv64_t *dyn, int next);
int is_nops(dynarec_rv64_t *dyn, uintptr_t addr, int n);
int is_instructions(dynarec_rv64_t *dyn, uintptr_t addr, int n);
@@ -139,12 +144,12 @@ int Table64(dynarec_rv64_t *dyn, uint64_t val, int pass); // add a value to tab
void CreateJmpNext(void* addr, void* next);
-#define GO_TRACE(A, B) \
+#define GO_TRACE(A, B, s0) \
GETIP(addr); \
MV(A1, xRIP); \
- STORE_XEMU_CALL(); \
+ STORE_XEMU_CALL(s0); \
MOV64x(A2, B); \
CALL(A, -1); \
LOAD_XEMU_CALL()
-#endif //__DYNAREC_RV64_PRIVATE_H_ \ No newline at end of file
+#endif //__DYNAREC_RV64_PRIVATE_H_
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index f23c671..ae95664 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -30,625 +30,1067 @@ f18–27 fs2–11 FP saved registers Callee
f28–31 ft8–11 FP temporaries Caller
*/
// x86 Register mapping
-#define xRAX 16
-#define xRCX 17
-#define xRDX 18
-#define xRBX 19
-#define xRSP 20
-#define xRBP 21
-#define xRSI 22
-#define xRDI 23
-#define xR8 24
-#define xR9 25
-#define xR10 26
-#define xR11 27
-#define xR12 28
-#define xR13 29
-#define xR14 30
-#define xR15 31
-#define xFlags 8
-#define xRIP 7
+#define xRAX 16
+#define xRCX 17
+#define xRDX 18
+#define xRBX 19
+#define xRSP 20
+#define xRBP 21
+#define xRSI 22
+#define xRDI 23
+#define xR8 24
+#define xR9 25
+#define xR10 26
+#define xR11 27
+#define xR12 28
+#define xR13 29
+#define xR14 30
+#define xR15 31
+#define xFlags 8
+#define xRIP 7
// 32bits version
-#define wEAX xRAX
-#define wECX xRCX
-#define wEDX xRDX
-#define wEBX xRBX
-#define wESP xRSP
-#define wEBP xRBP
-#define wESI xRSI
-#define wEDI xRDI
-#define wR8 xR8
-#define wR9 xR9
-#define wR10 xR10
-#define wR11 xR11
-#define wR12 xR12
-#define wR13 xR13
-#define wR14 xR14
-#define wR15 xR15
-#define wFlags xFlags
+#define wEAX xRAX
+#define wECX xRCX
+#define wEDX xRDX
+#define wEBX xRBX
+#define wESP xRSP
+#define wEBP xRBP
+#define wESI xRSI
+#define wEDI xRDI
+#define wR8 xR8
+#define wR9 xR9
+#define wR10 xR10
+#define wR11 xR11
+#define wR12 xR12
+#define wR13 xR13
+#define wR14 xR14
+#define wR15 xR15
+#define wFlags xFlags
// scratch registers
-#define x1 11
-#define x2 12
-#define x3 13
-#define x4 14
-#define x5 15
-#define x6 6
-#define x9 9
+#define x1 11
+#define x2 12
+#define x3 13
+#define x4 14
+#define x5 15
+#define x6 6
+#define x9 9
// used to clear the upper 32bits
-#define xMASK 5
+#define xMASK 5
// 32bits version of scratch
-#define w1 x1
-#define w2 x2
-#define w3 x3
-#define w4 x4
-#define w5 x5
-#define w6 x6
+#define w1 x1
+#define w2 x2
+#define w3 x3
+#define w4 x4
+#define w5 x5
+#define w6 x6
// emu is r10
-#define xEmu 10
+#define xEmu 10
// RV64 RA
-#define xRA 1
-#define xSP 2
+#define xRA 1
+#define xSP 2
// RV64 args
-#define A0 10
-#define A1 11
-#define A2 12
-#define A3 13
-#define A4 14
-#define A5 15
-#define A6 16
-#define A7 17
+#define A0 10
+#define A1 11
+#define A2 12
+#define A3 13
+#define A4 14
+#define A5 15
+#define A6 16
+#define A7 17
// xZR reg is 0
-#define xZR 0
-#define wZR xZR
+#define xZR 0
+#define wZR xZR
// replacement for F_OF internaly, using a reserved bit. Need to use F_OF2 internaly, never F_OF directly!
-#define F_OF2 F_res3
+#define F_OF2 F_res3
// split a 32bits value in 20bits + 12bits, adjust the upper part is 12bits is negative
-#define SPLIT20(A) (((A)+0x800)>>12)
-#define SPLIT12(A) ((A)&0xfff)
+#define SPLIT20(A) (((A) + 0x800) >> 12)
+#define SPLIT12(A) ((A)&0xfff)
// MOV64x/MOV32w is quite complex, so use a function for this
-#define MOV64x(A, B) rv64_move64(dyn, ninst, A, B)
-#define MOV32w(A, B) rv64_move32(dyn, ninst, A, B, 1)
-#define MOV64xw(A, B) if(rex.w) {MOV64x(A, B);} else {MOV32w(A, B);}
-#define MOV64z(A, B) if(rex.is32bits) {MOV32w(A, B);} else {MOV64x(A, B);}
+#define MOV64x(A, B) rv64_move64(dyn, ninst, A, B)
+#define MOV32w(A, B) rv64_move32(dyn, ninst, A, B, 1)
+#define MOV64xw(A, B) \
+ if (rex.w) { \
+ MOV64x(A, B); \
+ } else { \
+ MOV32w(A, B); \
+ }
+#define MOV64z(A, B) \
+ if (rex.is32bits) { \
+ MOV32w(A, B); \
+ } else { \
+ MOV64x(A, B); \
+ }
// ZERO the upper part
-#define ZEROUP(r) AND(r, r, xMASK)
+#define ZEROUP(r) AND(r, r, xMASK)
-#define R_type(funct7, rs2, rs1, funct3, rd, opcode) ((funct7)<<25 | (rs2)<<20 | (rs1)<<15 | (funct3)<<12 | (rd)<<7 | (opcode))
-#define I_type(imm12, rs1, funct3, rd, opcode) ((imm12)<<20 | (rs1)<<15 | (funct3)<<12 | (rd)<<7 | (opcode))
-#define S_type(imm12, rs2, rs1, funct3, opcode) (((imm12)>>5)<<25 | (rs2)<<20 | (rs1)<<15 | (funct3)<<12 | ((imm12)&31)<<7 | (opcode))
-#define B_type(imm13, rs2, rs1, funct3, opcode) ((((imm13)>>12)&1)<<31 | (((imm13)>>5)&63)<<25 | (rs2)<<20 | (rs1)<<15 | (funct3)<<12 | (((imm13)>>1)&15)<<8 | (((imm13)>>11)&1)<<7 | (opcode))
-#define U_type(imm32, rd, opcode) (((imm32)>>12)<<12 | (rd)<<7 | (opcode))
-#define J_type(imm21, rd, opcode) ((((imm21)>>20)&1)<<31 | (((imm21)>>1)&0b1111111111)<<21 | (((imm21)>>11)&1)<<20 | (((imm21)>>12)&0b11111111)<<12 | (rd)<<7 | (opcode))
+#define R_type(funct7, rs2, rs1, funct3, rd, opcode) ((funct7) << 25 | (rs2) << 20 | (rs1) << 15 | (funct3) << 12 | (rd) << 7 | (opcode))
+#define I_type(imm12, rs1, funct3, rd, opcode) ((imm12) << 20 | (rs1) << 15 | (funct3) << 12 | (rd) << 7 | (opcode))
+#define S_type(imm12, rs2, rs1, funct3, opcode) (((imm12) >> 5) << 25 | (rs2) << 20 | (rs1) << 15 | (funct3) << 12 | ((imm12)&31) << 7 | (opcode))
+#define B_type(imm13, rs2, rs1, funct3, opcode) ((((imm13) >> 12) & 1) << 31 | (((imm13) >> 5) & 63) << 25 | (rs2) << 20 | (rs1) << 15 | (funct3) << 12 | (((imm13) >> 1) & 15) << 8 | (((imm13) >> 11) & 1) << 7 | (opcode))
+#define U_type(imm32, rd, opcode) (((imm32) >> 12) << 12 | (rd) << 7 | (opcode))
+#define J_type(imm21, rd, opcode) ((((imm21) >> 20) & 1) << 31 | (((imm21) >> 1) & 0b1111111111) << 21 | (((imm21) >> 11) & 1) << 20 | (((imm21) >> 12) & 0b11111111) << 12 | (rd) << 7 | (opcode))
// RV32I
// put imm20 in the [31:12] bits of rd, zero [11:0] and sign extend bits31
-#define LUI(rd, imm20) EMIT(U_type((imm20)<<12, rd, 0b0110111))
+#define LUI(rd, imm20) EMIT(U_type((imm20) << 12, rd, 0b0110111))
// put PC+imm20 in rd
-#define AUIPC(rd, imm20) EMIT(U_type((imm20)<<12, rd, 0b0010111))
+#define AUIPC(rd, imm20) EMIT(U_type((imm20) << 12, rd, 0b0010111))
-#define JAL_gen(rd, imm21) J_type(imm21, rd, 0b1101111)
+#define JAL_gen(rd, imm21) J_type(imm21, rd, 0b1101111)
// Unconditional branch, no return address set
-#define B(imm21) EMIT(JAL_gen(xZR, imm21))
-#define B__(reg1, reg2, imm21) B(imm21)
+#define B(imm21) EMIT(JAL_gen(xZR, imm21))
+#define B__(reg1, reg2, imm21) B(imm21)
// Unconditional branch, return set to xRA
-#define JAL(imm21) EMIT(JAL_gen(xRA, imm21))
+#define JAL(imm21) EMIT(JAL_gen(xRA, imm21))
// Unconditional branch, without link
-#define J(imm21) EMIT(JAL_gen(xZR, imm21))
+#define J(imm21) EMIT(JAL_gen(xZR, imm21))
-#define JALR_gen(rd, rs1, imm12) I_type(imm12, rs1, 0b000, rd, 0b1100111)
+#define JALR_gen(rd, rs1, imm12) I_type(imm12, rs1, 0b000, rd, 0b1100111)
// Unconditionnal branch to r, no return address set
-#define BR(r) EMIT(JALR_gen(xZR, r, 0))
+#define BR(r) EMIT(JALR_gen(xZR, r, 0))
// Unconditionnal branch to r+i12, no return address set
-#define BR_I12(r, imm12) EMIT(JALR_gen(xZR, r, (imm12)&0b111111111111))
+#define BR_I12(r, imm12) EMIT(JALR_gen(xZR, r, (imm12)&0b111111111111))
// Unconditionnal branch to r, return address set to xRA
-#define JALR(r) EMIT(JALR_gen(xRA, r, 0))
+#define JALR(r) EMIT(JALR_gen(xRA, r, 0))
// Unconditionnal branch to r+i12, return address set to xRA
-#define JALR_I12(r, imm12) EMIT(JALR_gen(xRA, r, (imm12)&0b111111111111))
+#define JALR_I12(r, imm12) EMIT(JALR_gen(xRA, r, (imm12)&0b111111111111))
// rd = rs1 + imm12
-#define ADDI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, 0b0010011))
+#define ADDI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, 0b0010011))
// rd = rs1 - imm12 (pseudo instruction)
-#define SUBI(rd, rs1, imm12) EMIT(I_type((-(imm12))&0b111111111111, rs1, 0b000, rd, 0b0010011))
+#define SUBI(rd, rs1, imm12) EMIT(I_type((-(imm12)) & 0b111111111111, rs1, 0b000, rd, 0b0010011))
// rd = (rs1<imm12)?1:0
-#define SLTI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b010, rd, 0b0010011))
+#define SLTI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b010, rd, 0b0010011))
// rd = (rs1<imm12)?1:0 unsigned
-#define SLTIU(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b011, rd, 0b0010011))
+#define SLTIU(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b011, rd, 0b0010011))
// rd = rs1 ^ imm12
-#define XORI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b100, rd, 0b0010011))
+#define XORI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b100, rd, 0b0010011))
// rd = rs1 | imm12
-#define ORI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b110, rd, 0b0010011))
+#define ORI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b110, rd, 0b0010011))
// rd = rs1 & imm12
-#define ANDI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b111, rd, 0b0010011))
+#define ANDI(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b111, rd, 0b0010011))
// rd = imm12
-#define MOV_U12(rd, imm12) ADDI(rd, xZR, imm12)
+#define MOV_U12(rd, imm12) ADDI(rd, xZR, imm12)
// nop
-#define NOP() ADDI(xZR, xZR, 0)
+#define NOP() ADDI(xZR, xZR, 0)
// rd = rs1 + rs2
-#define ADD(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, 0b0110011))
+#define ADD(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, 0b0110011))
// rd = rs1 + rs2
-#define ADDW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, 0b0111011))
+#define ADDW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, 0b0111011))
// rd = rs1 + rs2
-#define ADDxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011))
+#define ADDxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, rex.w ? 0b0110011 : 0b0111011))
// rd = rs1 + rs2
-#define ADDz(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, rex.is32bits?0b0111011:0b0110011))
+#define ADDz(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b000, rd, rex.is32bits ? 0b0111011 : 0b0110011))
// rd = rs1 - rs2
-#define SUB(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, 0b0110011))
+#define SUB(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, 0b0110011))
// rd = rs1 - rs2
-#define SUBW(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, 0b0111011))
+#define SUBW(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, 0b0111011))
// rd = rs1 - rs2
-#define SUBxw(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011))
+#define SUBxw(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.w ? 0b0110011 : 0b0111011))
// rd = rs1 - rs2
-#define SUBz(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.is32bits?0b0111011:0b0110011))
+#define SUBz(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b000, rd, rex.is32bits ? 0b0111011 : 0b0110011))
// rd = rs1<<rs2
-#define SLL(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, 0b0110011))
+#define SLL(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, 0b0110011))
// rd = (rs1<rs2)?1:0
-#define SLT(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b010, rd, 0b0110011))
+#define SLT(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b010, rd, 0b0110011))
// rd = (rs1<rs2)?1:0 Unsigned
-#define SLTU(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b011, rd, 0b0110011))
+#define SLTU(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b011, rd, 0b0110011))
// rd = rs1 ^ rs2
-#define XOR(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b100, rd, 0b0110011))
+#define XOR(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b100, rd, 0b0110011))
// rd = rs1 ^ rs2
-#define XORxw(rd, rs1, rs2) do{ XOR(rd, rs1, rs2); if (!rex.w) ZEROUP(rd); }while(0)
+#define XORxw(rd, rs1, rs2) \
+ do { \
+ XOR(rd, rs1, rs2); \
+ if (!rex.w) ZEROUP(rd); \
+ } while (0)
// rd = rs1>>rs2 logical
-#define SRL(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, 0b0110011))
+#define SRL(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, 0b0110011))
// rd = rs1>>rs2 arithmetic
-#define SRA(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b101, rd, 0b0110011))
+#define SRA(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b101, rd, 0b0110011))
// rd = rs1 | rs2
-#define OR(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b110, rd, 0b0110011))
+#define OR(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b110, rd, 0b0110011))
// rd = rs1 & rs2
-#define AND(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b111, rd, 0b0110011))
+#define AND(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b111, rd, 0b0110011))
// rd = rs1 (pseudo instruction)
-#define MV(rd, rs1) ADDI(rd, rs1, 0)
+#define MV(rd, rs1) ADDI(rd, rs1, 0)
// rd = rs1 (pseudo instruction)
-#define MVxw(rd, rs1) if(rex.w) {MV(rd, rs1);} else {AND(rd, rs1, xMASK);}
+#define MVxw(rd, rs1) \
+ if (rex.w) { \
+ MV(rd, rs1); \
+ } else { \
+ AND(rd, rs1, xMASK); \
+ }
// rd = rs1 (pseudo instruction)
-#define MVz(rd, rs1) if(rex.is32bits) {AND(rd, rs1, xMASK);} else {MV(rd, rs1);}
+#define MVz(rd, rs1) \
+ if (rex.is32bits) { \
+ AND(rd, rs1, xMASK); \
+ } else { \
+ MV(rd, rs1); \
+ }
// rd = !rs1
-#define NOT(rd, rs1) XORI(rd, rs1, -1)
+#define NOT(rd, rs1) XORI(rd, rs1, -1)
// rd = -rs1
-#define NEG(rd, rs1) SUB(rd, xZR, rs1)
+#define NEG(rd, rs1) SUB(rd, xZR, rs1)
// rd = -rs1
-#define NEGxw(rd, rs1) SUBxw(rd, xZR, rs1)
+#define NEGxw(rd, rs1) SUBxw(rd, xZR, rs1)
// rd = rs1 == 0
-#define SEQZ(rd, rs1) SLTIU(rd, rs1, 1)
+#define SEQZ(rd, rs1) SLTIU(rd, rs1, 1)
// rd = rs1 != 0
-#define SNEZ(rd, rs1) SLTU(rd, xZR, rs1)
+#define SNEZ(rd, rs1) SLTU(rd, xZR, rs1)
-#define BEQ(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b000, 0b1100011))
-#define BNE(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b001, 0b1100011))
-#define BLT(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b100, 0b1100011))
-#define BGE(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b101, 0b1100011))
-#define BLTU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b110, 0b1100011))
-#define BGEU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b111, 0b1100011))
+#define BEQ(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b000, 0b1100011))
+#define BNE(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b001, 0b1100011))
+#define BLT(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b100, 0b1100011))
+#define BGE(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b101, 0b1100011))
+#define BLTU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b110, 0b1100011))
+#define BGEU(rs1, rs2, imm13) EMIT(B_type(imm13, rs2, rs1, 0b111, 0b1100011))
// TODO: Find a better way to have conditionnal jumps? Imm is a relative jump address, so the the 2nd jump needs to be addapted
-#define BEQ_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BEQ(rs1, rs2, imm); NOP();} else {BNE(rs1, rs2, 8); B(imm-4);}
-#define BNE_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BNE(rs1, rs2, imm); NOP();} else {BEQ(rs1, rs2, 8); B(imm-4);}
-#define BLT_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BLT(rs1, rs2, imm); NOP();} else {BGE(rs2, rs1, 8); B(imm-4);}
-#define BGE_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BGE(rs1, rs2, imm); NOP();} else {BLT(rs2, rs1, 8); B(imm-4);}
-#define BLTU_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BLTU(rs1, rs2, imm); NOP();} else {BGEU(rs2, rs1, 8); B(imm-4);}
-#define BGEU_safe(rs1, rs2, imm) if((imm)>-0x1000 && (imm)<0x1000) {BGEU(rs1, rs2, imm); NOP();} else {BLTU(rs2, rs1, 8); B(imm-4);}
+#define BEQ_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BEQ(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BNE(rs1, rs2, 8); \
+ B(imm - 4); \
+ }
+#define BNE_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BNE(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BEQ(rs1, rs2, 8); \
+ B(imm - 4); \
+ }
+#define BLT_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BLT(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BGE(rs2, rs1, 8); \
+ B(imm - 4); \
+ }
+#define BGE_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BGE(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BLT(rs2, rs1, 8); \
+ B(imm - 4); \
+ }
+#define BLTU_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BLTU(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BGEU(rs2, rs1, 8); \
+ B(imm - 4); \
+ }
+#define BGEU_safe(rs1, rs2, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BGEU(rs1, rs2, imm); \
+ NOP(); \
+ } else { \
+ BLTU(rs2, rs1, 8); \
+ B(imm - 4); \
+ }
-#define BEQZ(rs1, imm13) BEQ(rs1, 0, imm13)
-#define BNEZ(rs1, imm13) BNE(rs1, 0, imm13)
+#define BEQZ(rs1, imm13) BEQ(rs1, 0, imm13)
+#define BNEZ(rs1, imm13) BNE(rs1, 0, imm13)
-#define BEQZ_safe(rs1, imm) if((imm)>-0x1000 && (imm)<0x1000) {BEQZ(rs1, imm); NOP();} else {BNEZ(rs1, 8); B(imm-4);}
-#define BNEZ_safe(rs1, imm) if((imm)>-0x1000 && (imm)<0x1000) {BNEZ(rs1, imm); NOP();} else {BEQZ(rs1, 8); B(imm-4);}
+#define BEQZ_safe(rs1, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BEQZ(rs1, imm); \
+ NOP(); \
+ } else { \
+ BNEZ(rs1, 8); \
+ B(imm - 4); \
+ }
+#define BNEZ_safe(rs1, imm) \
+ if ((imm) > -0x1000 && (imm) < 0x1000) { \
+ BNEZ(rs1, imm); \
+ NOP(); \
+ } else { \
+ BEQZ(rs1, 8); \
+ B(imm - 4); \
+ }
// rd = 4-bytes[rs1+imm12] signed extended
-#define LW(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, rd, 0b0000011))
+#define LW(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, rd, 0b0000011))
// rd = 2-bytes[rs1+imm12] signed extended
-#define LH(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b001, rd, 0b0000011))
+#define LH(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b001, rd, 0b0000011))
// rd = byte[rs1+imm12] signed extended
-#define LB(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b000, rd, 0b0000011))
+#define LB(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b000, rd, 0b0000011))
// rd = 2-bytes[rs1+imm12] zero extended
-#define LHU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b101, rd, 0b0000011))
+#define LHU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b101, rd, 0b0000011))
// rd = byte[rs1+imm12] zero extended
-#define LBU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b100, rd, 0b0000011))
+#define LBU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b100, rd, 0b0000011))
// byte[rs1+imm12] = rs2
-#define SB(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b000, 0b0100011))
+#define SB(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b000, 0b0100011))
// 2-bytes[rs1+imm12] = rs2
-#define SH(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b001, 0b0100011))
+#define SH(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b001, 0b0100011))
// 4-bytes[rs1+imm12] = rs2
-#define SW(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010, 0b0100011))
+#define SW(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010, 0b0100011))
-#define PUSH1(reg) do {SD(reg, xRSP, -8); SUBI(xRSP, xRSP, 8);} while(0)
-#define POP1(reg) do {LD(reg, xRSP, 0); if (reg!=xRSP) ADDI(xRSP, xRSP, 8);} while(0)
-#define PUSH1_32(reg) do {SW(reg, xRSP, -4); SUBIW(xRSP, xRSP, 4);} while(0)
-#define POP1_32(reg) do {LWU(reg, xRSP, 0); if (reg!=xRSP) ADDIW(xRSP, xRSP, 4);} while(0)
+#define PUSH1(reg) \
+ do { \
+ SD(reg, xRSP, -8); \
+ SUBI(xRSP, xRSP, 8); \
+ } while (0)
+#define POP1(reg) \
+ do { \
+ LD(reg, xRSP, 0); \
+ if (reg != xRSP) ADDI(xRSP, xRSP, 8); \
+ } while (0)
+#define PUSH1_32(reg) \
+ do { \
+ SW(reg, xRSP, -4); \
+ SUBIW(xRSP, xRSP, 4); \
+ } while (0)
+#define POP1_32(reg) \
+ do { \
+ LWU(reg, xRSP, 0); \
+ if (reg != xRSP) ADDIW(xRSP, xRSP, 4); \
+ } while (0)
-#define POP1z(reg) if(rex.is32bits) {POP1_32(reg);} else {POP1(reg);}
-#define PUSH1z(reg) if(rex.is32bits) {PUSH1_32(reg);} else {PUSH1(reg);}
+#define POP1z(reg) \
+ if (rex.is32bits) { \
+ POP1_32(reg); \
+ } else { \
+ POP1(reg); \
+ }
+#define PUSH1z(reg) \
+ if (rex.is32bits) { \
+ PUSH1_32(reg); \
+ } else { \
+ PUSH1(reg); \
+ }
-#define FENCE_gen(pred, succ) (((pred)<<24) | ((succ)<<20) | 0b0001111)
-#define FENCE() EMIT(FENCE_gen(3, 3))
+#define FENCE_gen(pred, succ) (((pred) << 24) | ((succ) << 20) | 0b0001111)
+#define FENCE() EMIT(FENCE_gen(3, 3))
-#define FENCE_I_gen() ((0b001<<12) | 0b0001111)
-#define FENCE_I() EMIT(FENCE_I_gen())
+#define FENCE_I_gen() ((0b001 << 12) | 0b0001111)
+#define FENCE_I() EMIT(FENCE_I_gen())
-#define EBREAK() EMIT(I_type(1, 0, 0, 0, 0b1110011))
+#define EBREAK() EMIT(I_type(1, 0, 0, 0, 0b1110011))
// RV64I
-#define LWU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b110, rd, 0b0000011))
+#define LWU(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b110, rd, 0b0000011))
// rd = [rs1 + imm12]
-#define LD(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011, rd, 0b0000011))
+#define LD(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011, rd, 0b0000011))
// rd = [rs1 + imm12]
-#define LDxw(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011<<(1-rex.w), rd, 0b0000011))
+#define LDxw(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011 << (1 - rex.w), rd, 0b0000011))
// rd = [rs1 + imm12]
-#define LDz(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011<<rex.is32bits, rd, 0b0000011))
+#define LDz(rd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011 << rex.is32bits, rd, 0b0000011))
// [rs1 + imm12] = rs2
-#define SD(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b011, 0b0100011))
+#define SD(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b011, 0b0100011))
// [rs1 + imm12] = rs2
-#define SDxw(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010+rex.w, 0b0100011))
+#define SDxw(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010 + rex.w, 0b0100011))
// [rs1 + imm12] = rs2
-#define SDz(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010+(1-rex.is32bits), 0b0100011))
+#define SDz(rs2, rs1, imm12) EMIT(S_type(imm12, rs2, rs1, 0b010 + (1 - rex.is32bits), 0b0100011))
// Shift Left Immediate
-#define SLLI(rd, rs1, imm6) EMIT(I_type(imm6, rs1, 0b001, rd, 0b0010011))
+#define SLLI(rd, rs1, imm6) EMIT(I_type(imm6, rs1, 0b001, rd, 0b0010011))
// Shift Right Logical Immediate
-#define SRLI(rd, rs1, imm6) EMIT(I_type(imm6, rs1, 0b101, rd, 0b0010011))
+#define SRLI(rd, rs1, imm6) EMIT(I_type(imm6, rs1, 0b101, rd, 0b0010011))
// Shift Right Arithmetic Immediate
-#define SRAI(rd, rs1, imm6) EMIT(I_type((imm6)|(0b010000<<6), rs1, 0b101, rd, 0b0010011))
+#define SRAI(rd, rs1, imm6) EMIT(I_type((imm6) | (0b010000 << 6), rs1, 0b101, rd, 0b0010011))
// rd = rs1 + imm12
-#define ADDIW(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, 0b0011011))
+#define ADDIW(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, 0b0011011))
// rd = rs1 - imm12
-#define SUBIW(rd, rs1, imm12) EMIT(I_type((-imm12)&0b111111111111, rs1, 0b000, rd, 0b0011011))
+#define SUBIW(rd, rs1, imm12) EMIT(I_type((-imm12) & 0b111111111111, rs1, 0b000, rd, 0b0011011))
// rd = rs1 + imm12
-#define ADDIxw(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, rex.w?0b0010011:0b0011011))
+#define ADDIxw(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, rex.w ? 0b0010011 : 0b0011011))
// rd = rs1 + imm12
-#define ADDIz(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, rex.is32bits?0b0011011:0b0010011))
+#define ADDIz(rd, rs1, imm12) EMIT(I_type((imm12)&0b111111111111, rs1, 0b000, rd, rex.is32bits ? 0b0011011 : 0b0010011))
-#define SEXT_W(rd, rs1) ADDIW(rd, rs1, 0)
+// rd = rs1 + (rs2 << imm2)
+#define ADDSL(rd, rs1, rs2, imm2, scratch) \
+ if (!(imm2)) { \
+ ADD(rd, rs1, rs2); \
+ } else if (rv64_zba) { \
+ SHxADD(rd, rs2, imm2, rs1); \
+ } else if (rv64_xtheadba) { \
+ TH_ADDSL(rd, rs1, rs2, imm2); \
+ } else { \
+ SLLI(scratch, rs2, imm2); \
+ ADD(rd, rs1, scratch); \
+ }
+
+#define SEXT_W(rd, rs1) ADDIW(rd, rs1, 0)
// rd = rs1<<rs2
-#define SLLW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, 0b0111011))
+#define SLLW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, 0b0111011))
// rd = rs1>>rs2 logical
-#define SRLW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, 0b0111011))
+#define SRLW(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, 0b0111011))
// rd = rs1>>rs2 arithmetic
-#define SRAW(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b101, rd, 0b0111011))
+#define SRAW(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b101, rd, 0b0111011))
-#define SLLxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, rex.w?0b0110011:0b0111011))
-#define SRLxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, rex.w?0b0110011:0b0111011))
-#define SRAxw(rd, rs1, rs2) if(rex.w) {SRA(rd, rs1, rs2);} else {SRAW(rd, rs1, rs2); ZEROUP(rd);}
+#define SLLxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b001, rd, rex.w ? 0b0110011 : 0b0111011))
+#define SRLxw(rd, rs1, rs2) EMIT(R_type(0b0000000, rs2, rs1, 0b101, rd, rex.w ? 0b0110011 : 0b0111011))
+#define SRAxw(rd, rs1, rs2) \
+ if (rex.w) { \
+ SRA(rd, rs1, rs2); \
+ } else { \
+ SRAW(rd, rs1, rs2); \
+ ZEROUP(rd); \
+ }
// Shift Left Immediate, 32-bit, sign-extended
-#define SLLIW(rd, rs1, imm5) EMIT(I_type(imm5, rs1, 0b001, rd, 0b0011011))
+#define SLLIW(rd, rs1, imm5) EMIT(I_type(imm5, rs1, 0b001, rd, 0b0011011))
// Shift Left Immediate
-#define SLLIxw(rd, rs1, imm) if (rex.w) { SLLI(rd, rs1, imm); } else { SLLIW(rd, rs1, imm); }
+#define SLLIxw(rd, rs1, imm) \
+ if (rex.w) { \
+ SLLI(rd, rs1, imm); \
+ } else { \
+ SLLIW(rd, rs1, imm); \
+ }
// Shift Right Logical Immediate, 32-bit, sign-extended
-#define SRLIW(rd, rs1, imm5) EMIT(I_type(imm5, rs1, 0b101, rd, 0b0011011))
+#define SRLIW(rd, rs1, imm5) EMIT(I_type(imm5, rs1, 0b101, rd, 0b0011011))
// Shift Right Logical Immediate
-#define SRLIxw(rd, rs1, imm) if (rex.w) { SRLI(rd, rs1, imm); } else { SRLIW(rd, rs1, imm); }
+#define SRLIxw(rd, rs1, imm) \
+ if (rex.w) { \
+ SRLI(rd, rs1, imm); \
+ } else { \
+ SRLIW(rd, rs1, imm); \
+ }
// Shift Right Arithmetic Immediate, 32-bit, sign-extended
-#define SRAIW(rd, rs1, imm5) EMIT(I_type((imm5)|(0b0100000<<5), rs1, 0b101, rd, 0b0011011))
+#define SRAIW(rd, rs1, imm5) EMIT(I_type((imm5) | (0b0100000 << 5), rs1, 0b101, rd, 0b0011011))
// Shift Right Arithmetic Immediate
-#define SRAIxw(rd, rs1, imm) if (rex.w) { SRAI(rd, rs1, imm); } else { SRAIW(rd, rs1, imm); }
+#define SRAIxw(rd, rs1, imm) \
+ if (rex.w) { \
+ SRAI(rd, rs1, imm); \
+ } else { \
+ SRAIW(rd, rs1, imm); \
+ }
-#define CSRRW(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b001, rd, 0b1110011))
-#define CSRRS(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b010, rd, 0b1110011))
-#define CSRRC(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b011, rd, 0b1110011))
-#define CSRRWI(rd, imm, csr) EMIT(I_type(csr, imm, 0b101, rd, 0b1110011))
-#define CSRRSI(rd, imm, csr) EMIT(I_type(csr, imm, 0b110, rd, 0b1110011))
-#define CSRRCI(rd, imm, csr) EMIT(I_type(csr, imm, 0b111, rd, 0b1110011))
+#define CSRRW(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b001, rd, 0b1110011))
+#define CSRRS(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b010, rd, 0b1110011))
+#define CSRRC(rd, rs1, csr) EMIT(I_type(csr, rs1, 0b011, rd, 0b1110011))
+#define CSRRWI(rd, imm, csr) EMIT(I_type(csr, imm, 0b101, rd, 0b1110011))
+#define CSRRSI(rd, imm, csr) EMIT(I_type(csr, imm, 0b110, rd, 0b1110011))
+#define CSRRCI(rd, imm, csr) EMIT(I_type(csr, imm, 0b111, rd, 0b1110011))
// RV32M
// rd =(lower) rs1 * rs2 (both signed)
-#define MUL(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0110011))
+#define MUL(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0110011))
// rd =(upper) rs1 * rs2 (both signed)
-#define MULH(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b001, rd, 0b0110011))
+#define MULH(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b001, rd, 0b0110011))
// rd =(upper) (signed)rs1 * (unsigned)rs2
-#define MULHSU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b010, rd, 0b0110011))
+#define MULHSU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b010, rd, 0b0110011))
// rd =(upper) rs1 * rs2 (both unsigned)
-#define MULHU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b011, rd, 0b0110011))
+#define MULHU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b011, rd, 0b0110011))
// rd =(upper) rs1 / rs2
-#define DIV(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, 0b0110011))
-#define DIVU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, 0b0110011))
+#define DIV(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, 0b0110011))
+#define DIVU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, 0b0110011))
// rd = rs1 mod rs2
-#define REM(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, 0b0110011))
-#define REMU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, 0b0110011))
+#define REM(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, 0b0110011))
+#define REMU(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, 0b0110011))
// RV64M
// rd = rs1 * rs2
-#define MULW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0111011))
+#define MULW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, 0b0111011))
// rd = rs1 * rs2
-#define MULxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, rex.w?0b0110011:0b0111011))
+#define MULxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b000, rd, rex.w ? 0b0110011 : 0b0111011))
// rd = rs1 / rs2
-#define DIVW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, 0b0111011))
-#define DIVxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, rex.w?0b0110011:0b0111011))
-#define DIVUW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, 0b0111011))
-#define DIVUxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, rex.w?0b0110011:0b0111011))
+#define DIVW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, 0b0111011))
+#define DIVxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b100, rd, rex.w ? 0b0110011 : 0b0111011))
+#define DIVUW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, 0b0111011))
+#define DIVUxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b101, rd, rex.w ? 0b0110011 : 0b0111011))
// rd = rs1 mod rs2
-#define REMW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, 0b0111011))
-#define REMxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, rex.w?0b0110011:0b0111011))
-#define REMUW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, 0b0111011))
-#define REMUxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, rex.w?0b0110011:0b0111011))
+#define REMW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, 0b0111011))
+#define REMxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b110, rd, rex.w ? 0b0110011 : 0b0111011))
+#define REMUW(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, 0b0111011))
+#define REMUxw(rd, rs1, rs2) EMIT(R_type(0b0000001, rs2, rs1, 0b111, rd, rex.w ? 0b0110011 : 0b0111011))
-#define AQ_RL(f5, aq, rl) ((f5 << 2) | ((aq&1) << 1) | (rl&1))
+#define AQ_RL(f5, aq, rl) ((f5 << 2) | ((aq & 1) << 1) | (rl & 1))
// RV32A
-#define LR_W(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b010, rd, 0b0101111))
-#define SC_W(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b010, rd, 0b0101111))
+#define LR_W(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b010, rd, 0b0101111))
+#define SC_W(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b010, rd, 0b0101111))
-#define AMOSWAP_W(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00001, aq, rl), rs2, rs1, 0b010, rd, 0b0101111))
+#define AMOSWAP_W(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00001, aq, rl), rs2, rs1, 0b010, rd, 0b0101111))
// RV64A
-#define LR_D(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b011, rd, 0b0101111))
-#define SC_D(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b011, rd, 0b0101111))
+#define LR_D(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b011, rd, 0b0101111))
+#define SC_D(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b011, rd, 0b0101111))
-#define LRxw(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b010|rex.w, rd, 0b0101111))
-#define SCxw(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b010|rex.w, rd, 0b0101111))
+#define LRxw(rd, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00010, aq, rl), 0, rs1, 0b010 | rex.w, rd, 0b0101111))
+#define SCxw(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00011, aq, rl), rs2, rs1, 0b010 | rex.w, rd, 0b0101111))
#define AMOSWAP_D(rd, rs2, rs1, aq, rl) EMIT(R_type(AQ_RL(0b00001, aq, rl), rs2, rs1, 0b011, rd, 0b0101111))
// RV32F
// Read round mode
-#define FRRM(rd) CSRRS(rd, xZR, 0x002)
+#define FRRM(rd) CSRRS(rd, xZR, 0x002)
// Swap round mode
-#define FSRM(rd, rs) CSRRW(rd, rs, 0x002)
+#define FSRM(rd, rs) CSRRW(rd, rs, 0x002)
// Write FP exception flags, immediate
-#define FSFLAGSI(imm) CSRRWI(xZR, imm, 0x0001)
+#define FSFLAGSI(imm) CSRRWI(xZR, imm, 0x0001)
// Read FP exception flags to rd
-#define FRFLAGS(rd) CSRRS(rd, xZR, 0x0001)
+#define FRFLAGS(rd) CSRRS(rd, xZR, 0x0001)
// Inexact
-#define FR_NX 0
+#define FR_NX 0
// Underflow
-#define FR_UF 1
+#define FR_UF 1
// Overflow
-#define FR_OF 2
+#define FR_OF 2
// Divide by Zero
-#define FR_DZ 3
+#define FR_DZ 3
// Invalid Operation
-#define FR_NV 4
+#define FR_NV 4
// Round to Nearest, ties to Even
-#define RD_RNE 0b000
+#define RD_RNE 0b000
// Round towards Zero
-#define RD_RTZ 0b001
+#define RD_RTZ 0b001
// Round Down (towards −∞)
-#define RD_RDN 0b010
+#define RD_RDN 0b010
// Round Up (towards +∞)
-#define RD_RUP 0b011
+#define RD_RUP 0b011
// Round to Nearest, ties to Max Magnitude
-#define RD_RMM 0b100
+#define RD_RMM 0b100
// In instruction’s rm field, selects dynamic rounding mode;
-#define RD_RM 0b111
-#define RD_DYN RD_RM
+#define RD_RM 0b111
+#define RD_DYN RD_RM
// load single precision from rs1+imm12 to frd
-#define FLW(frd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, frd, 0b0000111))
+#define FLW(frd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, frd, 0b0000111))
// store single precision frs2 to rs1+imm12
-#define FSW(frs2, rs1, imm12) EMIT(S_type(imm12, frs2, rs1, 0b010, 0b0100111))
+#define FSW(frs2, rs1, imm12) EMIT(S_type(imm12, frs2, rs1, 0b010, 0b0100111))
// store rs1 with rs2 sign bit to rd
-#define FSGNJS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b000, rd, 0b1010011))
+#define FSGNJS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b000, rd, 0b1010011))
// move rs1 to rd
-#define FMVS(rd, rs1) FSGNJS(rd, rs1, rs1)
+#define FMVS(rd, rs1) FSGNJS(rd, rs1, rs1)
// store rs1 with oposite rs2 sign bit to rd
-#define FSGNJNS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b001, rd, 0b1010011))
+#define FSGNJNS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b001, rd, 0b1010011))
// -rs1 => rd
-#define FNEGS(rd, rs1) FSGNJNS(rd, rs1, rs1)
+#define FNEGS(rd, rs1) FSGNJNS(rd, rs1, rs1)
// store rs1 with rs1^rs2 sign bit to rd
-#define FSGNJXS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b1010011))
+#define FSGNJXS(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b1010011))
// |rs1| => rd
-#define FABSS(rd, rs1) FSGNJXS(rd, rs1, rs1)
+#define FABSS(rd, rs1) FSGNJXS(rd, rs1, rs1)
// Move from Single
-#define FMVXW(rd, frs1) EMIT(R_type(0b1110000, 0b00000, frs1, 0b000, rd, 0b1010011))
+#define FMVXW(rd, frs1) EMIT(R_type(0b1110000, 0b00000, frs1, 0b000, rd, 0b1010011))
// Move to Single
-#define FMVWX(frd, rs1) EMIT(R_type(0b1111000, 0b00000, rs1, 0b000, frd, 0b1010011))
+#define FMVWX(frd, rs1) EMIT(R_type(0b1111000, 0b00000, rs1, 0b000, frd, 0b1010011))
// Convert from signed 32bits to Single
-#define FCVTSW(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00000, rs1, rm, frd, 0b1010011))
+#define FCVTSW(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00000, rs1, rm, frd, 0b1010011))
// Convert from Single to signed 32bits (trucated)
-#define FCVTWS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00000, frs1, rm, rd, 0b1010011))
+#define FCVTWS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00000, frs1, rm, rd, 0b1010011))
-#define FADDS(frd, frs1, frs2) EMIT(R_type(0b0000000, frs2, frs1, 0b000, frd, 0b1010011))
-#define FSUBS(frd, frs1, frs2) EMIT(R_type(0b0000100, frs2, frs1, 0b000, frd, 0b1010011))
-#define FMULS(frd, frs1, frs2) EMIT(R_type(0b0001000, frs2, frs1, 0b000, frd, 0b1010011))
-#define FDIVS(frd, frs1, frs2) EMIT(R_type(0b0001100, frs2, frs1, 0b000, frd, 0b1010011))
-#define FSQRTS(frd, frs1) EMIT(R_type(0b0101100, 0b00000, frs1, 0b000, frd, 0b1010011))
-#define FMINS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b000, frd, 0b1010011))
-#define FMAXS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b001, frd, 0b1010011))
+#define FADDS(frd, frs1, frs2) EMIT(R_type(0b0000000, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSUBS(frd, frs1, frs2) EMIT(R_type(0b0000100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMULS(frd, frs1, frs2) EMIT(R_type(0b0001000, frs2, frs1, 0b000, frd, 0b1010011))
+#define FDIVS(frd, frs1, frs2) EMIT(R_type(0b0001100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSQRTS(frd, frs1) EMIT(R_type(0b0101100, 0b00000, frs1, 0b000, frd, 0b1010011))
+#define FMINS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMAXS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b001, frd, 0b1010011))
// compare
-#define FEQS(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b010, rd, 0b1010011))
-#define FLTS(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b001, rd, 0b1010011))
-#define FLES(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b000, rd, 0b1010011))
+#define FEQS(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b010, rd, 0b1010011))
+#define FLTS(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b001, rd, 0b1010011))
+#define FLES(rd, frs1, frs2) EMIT(R_type(0b1010000, frs2, frs1, 0b000, rd, 0b1010011))
// RV64F
// Convert from signed 64bits to Single
-#define FCVTSL(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00010, rs1, rm, frd, 0b1010011))
+#define FCVTSL(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00010, rs1, rm, frd, 0b1010011))
// Convert from unsigned 64bits to Single
-#define FCVTSLU(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00011, rs1, rm, frd, 0b1010011))
+#define FCVTSLU(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00011, rs1, rm, frd, 0b1010011))
// Convert from Single to signed 64bits
-#define FCVTLS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00010, frs1, rm, rd, 0b1010011))
+#define FCVTLS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00010, frs1, rm, rd, 0b1010011))
// Convert from Single to unsigned 64bits
-#define FCVTLUS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00011, frs1, rm, rd, 0b1010011))
+#define FCVTLUS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00011, frs1, rm, rd, 0b1010011))
// onvert from Single to signed 32/64bits (trucated)
-#define FCVTSxw(rd, frs1, rm) EMIT(R_type(0b1100000, rex.w?0b00010:0b00000, frs1, rm, rd, 0b1010011))
+#define FCVTSxw(rd, frs1, rm) EMIT(R_type(0b1100000, rex.w ? 0b00010 : 0b00000, frs1, rm, rd, 0b1010011))
// RV32D
// load double precision from rs1+imm12 to frd
-#define FLD(frd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011, frd, 0b0000111))
+#define FLD(frd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b011, frd, 0b0000111))
// store double precision frs2 to rs1+imm12
-#define FSD(frs2, rs1, imm12) EMIT(S_type(imm12, frs2, rs1, 0b011, 0b0100111))
+#define FSD(frs2, rs1, imm12) EMIT(S_type(imm12, frs2, rs1, 0b011, 0b0100111))
// Convert Double frs1 to Single frd
-#define FCVTSD(frd, frs1) EMIT(R_type(0b0100000, 0b00001, frs1, 0b000, frd, 0b1010011))
+#define FCVTSD(frd, frs1) EMIT(R_type(0b0100000, 0b00001, frs1, 0b000, frd, 0b1010011))
// Convert Single frs1 to Double frd
-#define FCVTDS(frd, frs1) EMIT(R_type(0b0100001, 0b00000, frs1, 0b000, frd, 0b1010011))
+#define FCVTDS(frd, frs1) EMIT(R_type(0b0100001, 0b00000, frs1, 0b000, frd, 0b1010011))
// Convert from Double to signed 32bits
-#define FCVTWD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00000, frs1, rm, rd, 0b1010011))
+#define FCVTWD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00000, frs1, rm, rd, 0b1010011))
// Convert from Double to unsigned 32bits
-#define FCVTWUD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00001, frs1, rm, rd, 0b1010011))
+#define FCVTWUD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00001, frs1, rm, rd, 0b1010011))
// store rs1 with rs2 sign bit to rd
-#define FSGNJD(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b000, rd, 0b1010011))
+#define FSGNJD(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b000, rd, 0b1010011))
// move rs1 to rd
-#define FMVD(rd, rs1) FSGNJD(rd, rs1, rs1)
+#define FMVD(rd, rs1) FSGNJD(rd, rs1, rs1)
// store rs1 with oposite rs2 sign bit to rd
-#define FSGNJND(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b001, rd, 0b1010011))
+#define FSGNJND(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b001, rd, 0b1010011))
// -rs1 => rd
-#define FNEGD(rd, rs1) FSGNJND(rd, rs1, rs1)
+#define FNEGD(rd, rs1) FSGNJND(rd, rs1, rs1)
// store rs1 with rs1^rs2 sign bit to rd
-#define FSGNJXD(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b010, rd, 0b1010011))
+#define FSGNJXD(rd, rs1, rs2) EMIT(R_type(0b0010001, rs2, rs1, 0b010, rd, 0b1010011))
// |rs1| => rd
-#define FABSD(rd, rs1) FSGNJXD(rd, rs1, rs1)
+#define FABSD(rd, rs1) FSGNJXD(rd, rs1, rs1)
// Convert from signed 32bits to Double
-#define FCVTDW(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00000, rs1, rm, frd, 0b1010011))
-
-#define FEQD(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b010, rd, 0b1010011))
-#define FLTD(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b001, rd, 0b1010011))
-#define FLED(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b000, rd, 0b1010011))
-
-#define FADDD(frd, frs1, frs2) EMIT(R_type(0b0000001, frs2, frs1, 0b000, frd, 0b1010011))
-#define FSUBD(frd, frs1, frs2) EMIT(R_type(0b0000101, frs2, frs1, 0b000, frd, 0b1010011))
-#define FMULD(frd, frs1, frs2) EMIT(R_type(0b0001001, frs2, frs1, 0b000, frd, 0b1010011))
-#define FDIVD(frd, frs1, frs2) EMIT(R_type(0b0001101, frs2, frs1, 0b000, frd, 0b1010011))
-#define FSQRTD(frd, frs1) EMIT(R_type(0b0101101, 0b00000, frs1, 0b000, frd, 0b1010011))
-#define FMIND(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b000, frd, 0b1010011))
-#define FMAXD(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b001, frd, 0b1010011))
-
-//RV64D
-// Move from Double
-#define FMVXD(rd, frs1) EMIT(R_type(0b1110001, 0b00000, frs1, 0b000, rd, 0b1010011))
+#define FCVTDW(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00000, rs1, rm, frd, 0b1010011))
+
+#define FEQD(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b010, rd, 0b1010011))
+#define FLTD(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b001, rd, 0b1010011))
+#define FLED(rd, frs1, frs2) EMIT(R_type(0b1010001, frs2, frs1, 0b000, rd, 0b1010011))
+
+#define FADDD(frd, frs1, frs2) EMIT(R_type(0b0000001, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSUBD(frd, frs1, frs2) EMIT(R_type(0b0000101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMULD(frd, frs1, frs2) EMIT(R_type(0b0001001, frs2, frs1, 0b000, frd, 0b1010011))
+#define FDIVD(frd, frs1, frs2) EMIT(R_type(0b0001101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSQRTD(frd, frs1) EMIT(R_type(0b0101101, 0b00000, frs1, 0b000, frd, 0b1010011))
+#define FMIND(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMAXD(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b001, frd, 0b1010011))
+
+// RV64D
+// Move from Double
+#define FMVXD(rd, frs1) EMIT(R_type(0b1110001, 0b00000, frs1, 0b000, rd, 0b1010011))
// Move to Double
-#define FMVDX(frd, rs1) EMIT(R_type(0b1111001, 0b00000, rs1, 0b000, frd, 0b1010011))
+#define FMVDX(frd, rs1) EMIT(R_type(0b1111001, 0b00000, rs1, 0b000, frd, 0b1010011))
// Convert from signed 64bits to Double
-#define FCVTDL(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00010, rs1, rm, frd, 0b1010011))
+#define FCVTDL(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00010, rs1, rm, frd, 0b1010011))
// Convert from unsigned 64bits to Double
-#define FCVTDLU(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00011, rs1, rm, frd, 0b1010011))
+#define FCVTDLU(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00011, rs1, rm, frd, 0b1010011))
// Convert from Double to signed 64bits
-#define FCVTLD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00010, frs1, rm, rd, 0b1010011))
+#define FCVTLD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00010, frs1, rm, rd, 0b1010011))
// Convert from Double to unsigned 64bits
-#define FCVTLUD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00011, frs1, rm, rd, 0b1010011))
+#define FCVTLUD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00011, frs1, rm, rd, 0b1010011))
// Convert from Double to signed integer
-#define FCVTLDxw(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00000+(rex.w?0b10:0b00), frs1, rm, rd, 0b1010011))
+#define FCVTLDxw(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00000 + (rex.w ? 0b10 : 0b00), frs1, rm, rd, 0b1010011))
// Convert from Double to unsigned integer
-#define FCVTLUDxw(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00001+(rex.w?0b10:0b00), frs1, rm, rd, 0b1010011))
+#define FCVTLUDxw(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00001 + (rex.w ? 0b10 : 0b00), frs1, rm, rd, 0b1010011))
-//Zba
-// Add unsigned word (Wz(rs1) + X(rs2))
-#define ADDUW(rd, rs1, rs2) EMIT(R_type(0b0000100, rs2, rs1, 0b000, rd, 0b0111011))
+// Zba
+// Add unsigned word (Wz(rs1) + X(rs2))
+#define ADDUW(rd, rs1, rs2) EMIT(R_type(0b0000100, rs2, rs1, 0b000, rd, 0b0111011))
// Zero-extend Word
-#define ZEXTW(rd, rs1) ADDUW(rd, rs1, xZR)
+#define ZEXTW(rd, rs1) ADDUW(rd, rs1, xZR)
// Shift left by 1 and add (rd = X(rs2) + X(rs1)<<1)
-#define SH1ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b0110011))
+#define SH1ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b0110011))
// Shift unsigned word left by 1 and add (rd = X(rs2) + Wz(rs1)<<1)
-#define SH1ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b0111011))
+#define SH1ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b010, rd, 0b0111011))
// Shift left by 2 and add (rd = X(rs2) + X(rs1)<<2)
-#define SH2ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b100, rd, 0b0110011))
+#define SH2ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b100, rd, 0b0110011))
// Shift unsigned word left by 2 and add (rd = X(rs2) + Wz(rs1)<<2)
-#define SH2ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b100, rd, 0b0111011))
+#define SH2ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b100, rd, 0b0111011))
// Shift left by 3 and add (rd = X(rs2) + X(rs1)<<3)
-#define SH3ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b110, rd, 0b0110011))
+#define SH3ADD(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b110, rd, 0b0110011))
// Shift unsigned word left by 3 and add (rd = X(rs2) + Wz(rs1)<<3)
-#define SH3ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b110, rd, 0b0111011))
+#define SH3ADDUW(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b110, rd, 0b0111011))
// Shift left unsigned word (immediate)
-#define SLLIUW(rd, rs1, imm) EMIT(R_type(0b0000100, imm, rs1, 0b001, rd, 0b0011011))
+#define SLLIUW(rd, rs1, imm) EMIT(R_type(0b0000100, imm, rs1, 0b001, rd, 0b0011011))
// Shift left by 1,2 or 3 and add (rd = X(rs2) + X(rs1)<<x)
-#define SHxADD(rd, rs1, x, rs2) EMIT(R_type(0b0010000, rs2, rs1, (x)<<1, rd, 0b0110011))
+#define SHxADD(rd, rs1, x, rs2) EMIT(R_type(0b0010000, rs2, rs1, (x) << 1, rd, 0b0110011))
// Shift unsigned word left by 1,2 or 3 and add (rd = X(rs2) + Wz(rs1)<<x)
-#define SHxADDUW(rd, rs1, x, rs2) EMIT(R_type(0b0010000, rs2, rs1, (x)<<1, rd, 0b0111011))
+#define SHxADDUW(rd, rs1, x, rs2) EMIT(R_type(0b0010000, rs2, rs1, (x) << 1, rd, 0b0111011))
-//Zbb
-// AND with reverted operand (rs1 & ~rs2)
-#define ANDN(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b111, rd, 0b0110011))
+// Zbb
+// AND with reverted operand (rs1 & ~rs2)
+#define ANDN(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b111, rd, 0b0110011))
// OR with reverted operand (rs1 | ~rs2)
-#define ORN(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b110, rd, 0b0110011))
+#define ORN(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b110, rd, 0b0110011))
// Exclusive NOR (~(rs1 ^ rs2))
-#define XNOR(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b100, rd, 0b0110011))
+#define XNOR(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b100, rd, 0b0110011))
// Count leading zero bits
-#define CLZ(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0010011))
+#define CLZ(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0010011))
// Count leading zero bits in word
-#define CLZW(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0011011))
+#define CLZW(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0011011))
// Count leading zero bits
-#define CLZxw(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, rex.w?0b0010011:0b0011011))
+#define CLZxw(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, rex.w ? 0b0010011 : 0b0011011))
// Count trailing zero bits
-#define CTZ(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, 0b0010011))
+#define CTZ(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, 0b0010011))
// Count trailing zero bits in word
-#define CTZW(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, 0b0011011))
+#define CTZW(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, 0b0011011))
// Count trailing zero bits
-#define CTZxw(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, rex.w?0b0010011:0b0011011))
+#define CTZxw(rd, rs) EMIT(R_type(0b0110000, 0b00001, rs, 0b001, rd, rex.w ? 0b0010011 : 0b0011011))
// Count set bits
-#define CPOP(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, 0b0010011))
+#define CPOP(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, 0b0010011))
// Count set bits in word
-#define CPOPW(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, 0b0011011))
+#define CPOPW(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, 0b0011011))
// Count set bits
-#define CPOPxw(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, rex.w?0b0010011:0b0011011))
+#define CPOPxw(rd, rs) EMIT(R_type(0b0110000, 0b00010, rs, 0b001, rd, rex.w ? 0b0010011 : 0b0011011))
// Maximum
-#define MAX(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b110, rd, 0b0110011))
+#define MAX(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b110, rd, 0b0110011))
// Unisgned maximum
-#define MAXU(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b111, rd, 0b0110011))
+#define MAXU(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b111, rd, 0b0110011))
// Minimum
-#define MIN(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b100, rd, 0b0110011))
+#define MIN(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b100, rd, 0b0110011))
// Unsigned minimum
-#define MINU(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b101, rd, 0b0110011))
+#define MINU(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b101, rd, 0b0110011))
// Sign-extend byte
-#define SEXTB(rd, rs) EMIT(R_type(0b0110000, 0b00100, rs, 0b001, rd, 0b0010011))
+#define SEXTB(rd, rs) EMIT(R_type(0b0110000, 0b00100, rs, 0b001, rd, 0b0010011))
// Sign-extend half-word
-#define SEXTH(rd, rs) EMIT(R_type(0b0110000, 0b00101, rs, 0b001, rd, 0b0010011))
+#define SEXTH(rd, rs) EMIT(R_type(0b0110000, 0b00101, rs, 0b001, rd, 0b0010011))
// Zero-extend half-word
-#define ZEXTH_(rd, rs) EMIT(R_type(0b0000100, 0b00000, rs, 0b100, rd, 0b0111011))
+#define ZEXTH_(rd, rs) EMIT(R_type(0b0000100, 0b00000, rs, 0b100, rd, 0b0111011))
// Zero-extend half-word
-#define ZEXTH(rd, rs) if(rv64_zbb) ZEXTH_(rd, rs); else {SLLI(rd, rs, 48); SRLI(rd, rd, 48);}
+#define ZEXTH(rd, rs) \
+ if (rv64_zbb) \
+ ZEXTH_(rd, rs); \
+ else { \
+ SLLI(rd, rs, 48); \
+ SRLI(rd, rd, 48); \
+ }
// Rotate left (register)
-#define ROL(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, 0b0110011))
+#define ROL(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, 0b0110011))
// Rotate left word (register)
-#define ROLW(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, 0b0111011))
+#define ROLW(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, 0b0111011))
// Rotate left (register)
-#define ROLxw(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, rex.w?0b0110011:0b0111011))
+#define ROLxw(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b001, rd, rex.w ? 0b0110011 : 0b0111011))
// Rotate right (register)
-#define ROR(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, 0b0110011))
+#define ROR(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, 0b0110011))
// Rotate right (immediate)
-#define RORI(rd, rs1, shamt) EMIT(R_type(0b0110000, shamt, rs1, 0b101, rd, 0b0010011))
+#define RORI(rd, rs1, shamt) EMIT(I_type((shamt) | (0b011000 << 6), rs1, 0b101, rd, 0b0010011))
// Rotate right word (immediate)
-#define RORIW(rd, rs1, shamt) EMIT(R_type(0b0110000, shamt, rs1, 0b101, rd, 0b0011011))
+#define RORIW(rd, rs1, shamt) EMIT(R_type(0b0110000, shamt, rs1, 0b101, rd, 0b0011011))
// Rotate right (immediate)
-#define RORIxw(rd, rs1, shamt) EMIT(R_type(0b0110000, shamt, rs1, 0b101, rd, rex.w?0b0010011:0b0011011))
+#define RORIxw(rd, rs1, shamt) EMIT(R_type(0b0110000, shamt, rs1, 0b101, rd, rex.w ? 0b0010011 : 0b0011011))
// Rotate right word (register)
-#define RORW(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, 0b0111011))
+#define RORW(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, 0b0111011))
// Rotate right (register)
-#define RORxw(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, rex.w?0b0110011:0b0111011))
+#define RORxw(rd, rs1, rs2) EMIT(R_type(0b0110000, rs2, rs1, 0b101, rd, rex.w ? 0b0110011 : 0b0111011))
// Bitwise OR Combine, byte granule (for all byte, if byte==0, res.byte=0, else res.byte=0xff)
-#define ORCB(rd, rs) EMIT(I_type(0b001010000111, rs, 0b101, rd, 0b0010011))
+#define ORCB(rd, rs) EMIT(I_type(0b001010000111, rs, 0b101, rd, 0b0010011))
// Byte-reverse register
-#define REV8(rd, rs) EMIT(I_type(0b011010111000, rs, 0b101, rd, 0b0010011))
+#define REV8(rd, rs) EMIT(I_type(0b011010111000, rs, 0b101, rd, 0b0010011))
+
+// Byte-reverse register, rd can be the same as rs or s1, but rs cannot be the same as s1.
+#define REV8xw(rd, rs, s1, s2, s3, s4) \
+ if (rv64_zbb) { \
+ REV8(rd, rs); \
+ if (!rex.w) { \
+ SRLI(rd, rd, 32); \
+ } \
+ } else if (rv64_xtheadbb) { \
+ if (rex.w) { \
+ TH_REV(rd, rs); \
+ } else { \
+ TH_REVW(rd, rs); \
+ } \
+ } else { \
+ MOV_U12(s2, 0xff); \
+ if (rex.w) { \
+ SLLI(s1, rs, 56); \
+ SRLI(s3, rs, 56); \
+ SRLI(s4, rs, 40); \
+ SLLI(s2, s2, 8); \
+ AND(s4, s4, s2); \
+ OR(s1, s1, s3); \
+ OR(s1, s1, s4); \
+ SLLI(s3, rs, 40); \
+ SLLI(s4, s2, 40); \
+ AND(s3, s3, s4); \
+ OR(s1, s1, s3); \
+ SRLI(s3, rs, 24); \
+ SLLI(s4, s2, 8); \
+ AND(s3, s3, s4); \
+ OR(s1, s1, s3); \
+ SLLI(s3, rs, 24); \
+ SLLI(s4, s2, 32); \
+ AND(s3, s3, s4); \
+ OR(s1, s1, s3); \
+ SRLI(s3, rs, 8); \
+ SLLI(s4, s2, 16); \
+ AND(s3, s3, s4); \
+ OR(s1, s1, s3); \
+ SLLI(s3, rs, 8); \
+ SLLI(s4, s2, 24); \
+ AND(s3, s3, s4); \
+ OR(rd, s1, s3); \
+ } else { \
+ SLLIW(s2, s2, 8); \
+ SLLIW(s1, rs, 24); \
+ SRLIW(s3, rs, 24); \
+ SRLIW(s4, rs, 8); \
+ AND(s4, s4, s2); \
+ OR(s1, s1, s3); \
+ OR(s1, s1, s4); \
+ SLLIW(s3, rs, 8); \
+ LUI(s2, 0xff0); \
+ AND(s3, s3, s2); \
+ OR(rd, s1, s3); \
+ } \
+ }
-//Zbc
-// Carry-less multily (low-part)
-#define CLMUL(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b001, rd, 0b0110011))
+// Zbc
+// Carry-less multily (low-part)
+#define CLMUL(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b001, rd, 0b0110011))
// Carry-less multiply (high-part)
-#define CLMULH(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b011, rd, 0b0110011))
+#define CLMULH(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b011, rd, 0b0110011))
// Carry-less multiply (reversed)
-#define CLMULR(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b010, rd, 0b0110011))
+#define CLMULR(rd, rs1, rs2) EMIT(R_type(0b0000101, rs2, rs1, 0b010, rd, 0b0110011))
-//Zbs
-// encoding of the "imm" on RV64 use a slight different mask, but it will work using R_type with high bit of imm ovewriting low bit op func
-// Single-bit Clear (Register)
-#define BCLR(rd, rs1, rs2) EMIT(R_type(0b0100100, rs2, rs1, 0b001, rd, 0b0110011))
+// Zbs
+// encoding of the "imm" on RV64 use a slight different mask, but it will work using R_type with high bit of imm ovewriting low bit op func
+// Single-bit Clear (Register)
+#define BCLR(rd, rs1, rs2) EMIT(R_type(0b0100100, rs2, rs1, 0b001, rd, 0b0110011))
// Single-bit Clear (Immediate)
-#define BCLI(rd, rs1, imm) EMIT(R_type(0b0100100, imm, rs1, 0b001, rd, 0b0010011))
-// Single-bit Extreact (Register)
-#define BEXT(rd, rs1, rs2) EMIT(R_type(0b0100100, rs2, rs1, 0b101, rd, 0b0110011))
+#define BCLI(rd, rs1, imm) EMIT(R_type(0b0100100, imm, rs1, 0b001, rd, 0b0010011))
+// Single-bit Extract (Register)
+#define BEXT_(rd, rs1, rs2) EMIT(R_type(0b0100100, rs2, rs1, 0b101, rd, 0b0110011))
// Single-bit Extract (Immediate)
-#define BEXTI(rd, rs1, imm) EMIT(R_type(0b0100100, imm, rs1, 0b101, rd, 0b0010011))
+#define BEXTI_(rd, rs1, shamt) EMIT(I_type((shamt) | (0b010010 << 6), rs1, 0b101, rd, 0b0010011))
// Single-bit Invert (Register)
-#define BINV(rd, rs1, rs2) EMIT(R_type(0b0110100, rs2, rs1, 0b001, rd, 0b0110011))
+#define BINV(rd, rs1, rs2) EMIT(R_type(0b0110100, rs2, rs1, 0b001, rd, 0b0110011))
// Single-bit Invert (Immediate)
-#define BINVI(rd, rs1, imm) EMIT(R_type(0b0110100, imm, rs1, 0b001, rd, 0b0010011))
+#define BINVI(rd, rs1, imm) EMIT(R_type(0b0110100, imm, rs1, 0b001, rd, 0b0010011))
// Single-bit Set (Register)
-#define BSET(rd, rs1, rs2) EMIT(R_type(0b0010100, rs2, rs1, 0b001, rd, 0b0110011))
+#define BSET(rd, rs1, rs2) EMIT(R_type(0b0010100, rs2, rs1, 0b001, rd, 0b0110011))
// Single-bit Set (Immediate)
-#define BSETI(rd, rs1, imm) EMIT(R_type(0b0010100, imm, rs1, 0b001, rd, 0b0010011))
+#define BSETI(rd, rs1, imm) EMIT(R_type(0b0010100, imm, rs1, 0b001, rd, 0b0010011))
+
+// Single-bit Extract (Register), s0 can be the same as rs2
+#define BEXT(rd, rs1, rs2, s0) \
+ if (rv64_zbs) \
+ BEXT_(rd, rs1, rs2); \
+ else { \
+ ANDI(s0, rs2, rex.w ? 0x3f : 0x1f); \
+ SRL(rd, rs1, s0); \
+ ANDI(rd, rd, 1); \
+ }
+
+// Single-bit Extract (Immediate)
+#define BEXTI(rd, rs1, imm) \
+ if (rv64_zbs) \
+ BEXTI_(rd, rs1, imm); \
+ else if (rv64_xtheadbs) \
+ TH_TST(rd, rs1, imm); \
+ else { \
+ SRLIxw(rd, rs1, imm); \
+ ANDI(rd, rd, 1); \
+ }
+
+/// THead vendor extension
+/// https://github.com/T-head-Semi/thead-extension-spec/releases
+
+// XTheadBa - Address calculation instructions
+
+// Add a shifted operand to a second operand.
+// reg[rd] := reg[rs1] + (reg[rs2] << imm2)
+#define TH_ADDSL(rd, rs1, rs2, imm2) EMIT(R_type((imm2)&0b11, rs2, rs1, 0b001, rd, 0b0001011))
+
+// XTheadBb - Basic bit-manipulation
+
+#define TH_SRRIxw(rd, rs1, imm) \
+ if (rex.w) { \
+ TH_SRRI(rd, rs1, imm); \
+ } else { \
+ TH_SRRIW(rd, rs1, imm); \
+ }
+
+// Perform a cyclic right shift.
+// reg[rd] := (reg[rs1] >> imm6) | (reg[rs1] << (xlen - imm6))
+#define TH_SRRI(rd, rs1, imm6) EMIT(I_type(0b000100000000 | ((imm6)&0x3f), rs1, 0b001, rd, 0b0001011))
+
+// Perform a cyclic right shift on word operand.
+// data := zext.w(reg[rs1])
+// reg[rd] := (data >> imm5) | (data << (32 - imm5))
+#define TH_SRRIW(rd, rs1, imm5) EMIT(I_type(0b000101000000 | ((imm5)&0x1f), rs1, 0b001, rd, 0b0001011))
+
+// Extract and sign-extend bits.
+// reg[rd] := sign_extend(reg[rs1][imm1:imm2])
+#define TH_EXT(rd, rs1, imm1, imm2) EMIT(I_type((((imm1)&0x1f) << 6) | ((imm2)&0x1f), rs1, 0b010, rd, 0b0001011))
+
+// Extract and zero-extend bits.
+// reg[rd] := zero_extend(reg[rs1][imm1:imm2])
+#define TH_EXTU(rd, rs1, imm1, imm2) EMIT(I_type((((imm1)&0x1f) << 6) | ((imm2)&0x1f), rs1, 0b011, rd, 0b0001011))
+
+// Find first '0'-bit
+// for i=xlen..0:
+// if reg[rs1][i] == 0:
+// break;
+// reg[rd] = (xlen - 1) - i
+#define TH_FF0(rd, rs1) EMIT(I_type(0b100001000000, rs1, 0b001, rd, 0b0001011))
+
+// Find first '1'-bit
+// for i=xlen..0:
+// if reg[rs1][i] == 1:
+// break;
+// reg[rd] = (xlen - 1) - i
+#define TH_FF1(rd, rs1) EMIT(I_type(0b100001100000, rs1, 0b001, rd, 0b0001011))
+
+// Reverse the byte order.
+// for i=0..(xlen/8-1):
+// j := xlen/8 - 1 - i
+// tmp[i] := reg[rs1][j]
+// reg[rd] := tmp
+#define TH_REV(rd, rs1) EMIT(I_type(0b100000100000, rs1, 0b001, rd, 0b0001011))
+
+// Reverse the byte order of a word operand.
+// for i=0..3:
+// j := 3 - i
+// tmp[i] := reg[rs1][j]
+// reg[rd] := tmp
+#define TH_REVW(rd, rs1) EMIT(I_type(0b100100000000, rs1, 0b001, rd, 0b0001011))
+
+// Test for NUL bytes.
+// for i=0..(xlen/8-1):
+// if reg[rs1][i] == 0:
+// reg[rd][i] := 0xff
+// else
+// reg[rd][i] := 0
+#define TH_TSTNBZ(rd, rs1) EMIT(I_type(0b1000000000000, rs1, 0b001, rd, 0b0001011))
+
+// XTheadBs - Single-bit instructions
+
+// Tests if a single bit is set.
+// if (reg[rs1] & (1 << imm6))
+// rd := 1
+// else
+// rd := 0
+#define TH_TST(rd, rs1, imm6) EMIT(I_type(0b100010000000 | ((imm6)&0x3f), rs1, 0b001, rd, 0b0001011))
+
+
+// XTheadCondMov - Conditional move
+
+// Move if equal zero.
+// if (reg[rs2] == 0x0)
+// reg[rd] := reg[rs1]
+#define TH_MVEQZ(rd, rs1, rs2) EMIT(R_type(0b0100000, rs2, rs1, 0b001, rd, 0b0001011))
+
+// Move if not equal zero.
+// if (reg[rs2] != 0x0)
+// reg[rd] := reg[rs1]
+#define TH_MVNEZ(rd, rs1, rs2) EMIT(R_type(0b0100001, rs2, rs1, 0b001, rd, 0b0001011))
+
+// XTheadMemIdx - Indexed memory operations
+
+// Load indexed byte, increment address after loading.
+// rd := sign_extend(mem[rs1])
+// rs1 := rs1 + (sign_extend(imm5) << imm2)
+#define TH_LBIA(rd, rs1, imm5, imm2) EMIT(I_type(0b000110000000 | (((imm2)&0b11) << 5) | ((imm5)&0x1f), rs1, 0b100, rd, 0b0001011))
+
+// TODO
+// th.lbib rd, (rs1), imm5, imm2 Load indexed byte
+// th.lbuia rd, (rs1), imm5, imm2 Load indexed unsigned byte
+// th.lbuib rd, (rs1), imm5, imm2 Load indexed unsigned byte
+// th.lhia rd, (rs1), imm5, imm2 Load indexed half-word
+// th.lhib rd, (rs1), imm5, imm2 Load indexed half-word
+// th.lhuia rd, (rs1), imm5, imm2 Load indexed unsigned half-word
+// th.lhuib rd, (rs1), imm5, imm2 Load indexed unsigned half-word
+// th.lwia rd, (rs1), imm5, imm2 Load indexed word
+// th.lwib rd, (rs1), imm5, imm2 Load indexed word
+// th.lwuia rd, (rs1), imm5, imm2 Load indexed unsigned word
+// th.lwuib rd, (rs1), imm5, imm2 Load indexed unsigned word
+// th.ldia rd, (rs1), imm5, imm2 Load indexed double-word
+// th.ldib rd, (rs1), imm5, imm2 Load indexed double-word
+// th.sbia rd, (rs1), imm5, imm2 Store indexed byte
+// th.sbib rd, (rs1), imm5, imm2 Store indexed byte
+// th.shia rd, (rs1), imm5, imm2 Store indexed half-word
+// th.shib rd, (rs1), imm5, imm2 Store indexed half-word
+// th.swia rd, (rs1), imm5, imm2 Store indexed word
+// th.swib rd, (rs1), imm5, imm2 Store indexed word
+// th.sdia rd, (rs1), imm5, imm2 Store indexed double-word
+// th.sdib rd, (rs1), imm5, imm2 Store indexed double-word
+// th.lrb rd, rs1, rs2, imm2 Load indexed byte
+// th.lrbu rd, rs1, rs2, imm2 Load indexed unsigned byte
+// th.lrh rd, rs1, rs2, imm2 Load indexed half-word
+// th.lrhu rd, rs1, rs2, imm2 Load indexed unsigned half-word
+// th.lrw rd, rs1, rs2, imm2 Load indexed word
+// th.lrwu rd, rs1, rs2, imm2 Load indexed unsigned word
+// th.lrd rd, rs1, rs2, imm2 Load indexed double-word
+// th.srb rd, rs1, rs2, imm2 Store indexed byte
+// th.srh rd, rs1, rs2, imm2 Store indexed half-word
+// th.srw rd, rs1, rs2, imm2 Store indexed word
+// th.srd rd, rs1, rs2, imm2 Store indexed double-word
+// th.lurb rd, rs1, rs2, imm2 Load unsigned indexed byte
+// th.lurbu rd, rs1, rs2, imm2 Load unsigned indexed unsigned byte
+// th.lurh rd, rs1, rs2, imm2 Load unsigned indexed half-word
+// th.lurhu rd, rs1, rs2, imm2 Load unsigned indexed unsigned half-word
+// th.lurw rd, rs1, rs2, imm2 Load unsigned indexed word
+// th.lurwu rd, rs1, rs2, imm2 Load unsigned indexed unsigned word
+// th.lurd rd, rs1, rs2, imm2 Load unsigned indexed double-word
+// th.surb rd, rs1, rs2, imm2 Store unsigned indexed byte
+// th.surh rd, rs1, rs2, imm2 Store unsigned indexed half-word
+// th.surw rd, rs1, rs2, imm2 Store unsigned indexed word
+// th.surd rd, rs1, rs2, imm2 Store unsigned indexed double-word
+
+// XTheadMemPair - Two-GPR memory operations
+
+
+// Load two 64-bit values from memory into two GPRs.
+// addr := rs1 + (zero_extend(imm2) << 4)
+// rd1 := mem[addr+7:addr]
+// rd2 := mem[addr+15:addr+8]
+#define TH_LDD(rd1, rd2, rs1, imm2) EMIT(R_type(0b1111100 | ((imm2)&0b11), rd2, rs1, 0b100, rd1, 0b0001011))
+
+// Load two signed 32-bit values from memory into two GPRs.
+// addr := rs1 + (zero_extend(imm2) << 3)
+// reg[rd1] := sign_extend(mem[addr+3:addr])
+// reg[rd2] := sign_extend(mem[addr+7:addr+4])
+#define TH_LWD(rd1, rd2, rs1, imm2) EMIT(R_type(0b1110000 | ((imm2)&0b11), rd2, rs1, 0b100, rd1, 0b0001011))
+
+// Load two unsigned 32-bit values from memory into two GPRs.
+// addr := rs1 + (zero_extend(imm2) << 3)
+// reg[rd1] := zero_extend(mem[addr+3:addr])
+// reg[rd2] := zero_extend(mem[addr+7:addr+4])
+#define TH_LWUD(rd1, rd2, rs1, imm2) EMIT(R_type(0b1111000 | ((imm2)&0b11), rd2, rs1, 0b100, rd1, 0b0001011))
+
+// Store two 64-bit values to memory from two GPRs.
+// addr := rs1 + (zero_extend(imm2) << 4)
+// mem[addr+7:addr] := reg[rd1]
+// mem[addr+15:addr+8] := reg[rd2]
+#define TH_SDD(rd1, rd2, rs1, imm2) EMIT(R_type(0b1111100 | ((imm2)&0b11), rd2, rs1, 0b101, rd1, 0b0001011))
+
+// Store two 32-bit values to memory from two GPRs.
+// addr := rs1 + (zero_extend(imm2) << 3)
+// mem[addr+3:addr] := reg[rd1][31:0]
+// mem[addr+7:addr+3] := reg[rd2][31:0]
+#define TH_SWD(rd1, rd2, rs1, imm2) EMIT(R_type(0b1110000 | ((imm2)&0b11), rd2, rs1, 0b101, rd1, 0b0001011))
+
+// XTheadFMemIdx - Indexed memory operations for floating-point registers
+
+// Load indexed double-precision floating point value.
+// addr := rs1 + (rs2 << imm2)
+// rd := fmem[addr+7:addr]
+#define TH_FLRD(rd, rs1, rs2, imm2) EMIT(R_type(0b0110000 | ((imm2)&0b11), rs2, rs1, 0b110, rd, 0b0001011))
+
+// TODO
+// th.flrw rd, rs1, rs2, imm2 Load indexed float
+// th.flurd rd, rs1, rs2, imm2 Load unsigned indexed double
+// th.flurw rd, rs1, rs2, imm2 Load unsigned indexed float
+// th.fsrd rd, rs1, rs2, imm2 Store indexed double
+// th.fsrw rd, rs1, rs2, imm2 Load indexed float
+// th.fsurd rd, rs1, rs2, imm2 Store unsigned indexed double
+// th.fsurw rd, rs1, rs2, imm2 Load unsigned indexed float
+
+// XTheadMac - Multiply-accumulate instructions
+
+// Compute multiply-add result of double-word operands.
+// M := reg[rs1] * reg[rs2]
+// reg[rd] := reg[rd] + M
+#define TH_MULA(rd, rs1, rs2) EMIT(R_type(0b0010000, rs2, rs1, 0b001, rd, 0b0001011))
+
+// TODO
+// th.mulah rd, rs1, rs2 Multiply-add half-words
+// th.mulaw rd, rs1, rs2 Multiply-add words
+// th.muls rd, rs1, rs2 Multiply-subtract double-words
+// th.mulsh rd, rs1, rs2 Multiply-subtract half-words
+// th.mulsw rd, rs1, rs2 Multiply-subtract words
+
+// XTheadFmv - Double-precision floating-point high-bit data transmission instructions
+
+// Read double-precision floating-point high-bit data
+// rd := fs1[63:32]
+#define TH_FMV_X_HW(rd, fs1) EMIT(R_type(0b1100000, 0, fs1, 0b001, rd, 0b0001011))
+// Write double-precision floating-point high-bit data
+// fs1[63:32] := rd
+#define TH_FMV_HW_X(rd, fs1) EMIT(R_type(0b1010000, 0, fs1, 0b001, rd, 0b0001011))
#endif //__RV64_EMITTER_H__
diff --git a/src/dynarec/rv64/rv64_lock.S b/src/dynarec/rv64/rv64_lock.S
index d6ea9c4..2b48163 100644
--- a/src/dynarec/rv64/rv64_lock.S
+++ b/src/dynarec/rv64/rv64_lock.S
@@ -17,9 +17,13 @@
.global rv64_lock_incif0
.global rv64_lock_decifnot0
.global rv64_lock_store
+.global rv64_lock_store_dd
.global rv64_lock_cas_d
.global rv64_lock_cas_dd
.global rv64_lock_cas_dq
+.global rv64_lock_get_b
+.global rv64_lock_get_d
+.global rv64_lock_get_dd
rv64_lock_xchg_dd:
// address is a0, value is a1, return old value in a0
@@ -202,6 +206,11 @@ rv64_lock_store:
fence rw, rw
ret
+rv64_lock_store_dd:
+ sd a1, 0(a0)
+ fence rw, rw
+ ret
+
rv64_lock_cas_d:
lr.w t0, (a0)
bne t0, a1, 1f
@@ -229,4 +238,19 @@ rv64_lock_cas_dq:
ret
1:
li a0, 1
- ret \ No newline at end of file
+ ret
+
+rv64_lock_get_b:
+ fence rw, rw
+ lb a0, 0(a0)
+ ret
+
+rv64_lock_get_d:
+ fence rw, rw
+ lw a0, 0(a0)
+ ret
+
+rv64_lock_get_dd:
+ fence rw, rw
+ ld a0, 0(a0)
+ ret
diff --git a/src/dynarec/rv64/rv64_lock.h b/src/dynarec/rv64/rv64_lock.h
index 33ce09a..8f9d95b 100644
--- a/src/dynarec/rv64/rv64_lock.h
+++ b/src/dynarec/rv64/rv64_lock.h
@@ -44,9 +44,21 @@ extern int rv64_lock_decifnot0(void*p);
// atomic store (with memory barrier)
extern void rv64_lock_store(void*p, uint32_t v);
+// atomic store (with memory barrier)
+extern void rv64_lock_store_dd(void*p, uint64_t v);
+
// (mostly) Atomically store val1 and val2 at [p] if old [p] is ref. Return 0 if OK, 1 is not. p needs to be aligned
extern int rv64_lock_cas_dq(void* p, uint64_t ref, uint64_t val1, uint64_t val2);
+// atomic get (with memory barrier)
+extern uint32_t rv64_lock_get_b(void* p);
+
+// atomic get (with memory barrier)
+extern uint32_t rv64_lock_get_d(void* p);
+
+// atomic get (with memory barrier)
+extern void* rv64_lock_get_dd(void* p);
+
// Not defined in assembler but in dynarec_rv64_functions
uint8_t extract_byte(uint32_t val, void* address);
uint32_t insert_byte(uint32_t val, uint8_t b, void* address);
diff --git a/src/dynarec/rv64/rv64_printer.c b/src/dynarec/rv64/rv64_printer.c
index db013c3..54f1ad5 100644
--- a/src/dynarec/rv64/rv64_printer.c
+++ b/src/dynarec/rv64/rv64_printer.c
@@ -13,6 +13,7 @@ typedef struct {
int8_t rs2;
int8_t rs3;
int32_t imm;
+ int32_t imm2;
uint16_t csr;
char *name;
bool rvc;
@@ -38,17 +39,20 @@ static const char fpnames[32][5] = {
/**
* normal types
*/
-#define OPCODE(data) (((data) >> 2) & 0x1f)
-#define RD(data) (((data) >> 7) & 0x1f)
-#define RS1(data) (((data) >> 15) & 0x1f)
-#define RS2(data) (((data) >> 20) & 0x1f)
-#define RS3(data) (((data) >> 27) & 0x1f)
-#define FUNCT2(data) (((data) >> 25) & 0x3 )
-#define FUNCT3(data) (((data) >> 12) & 0x7 )
-#define FUNCT7(data) (((data) >> 25) & 0x7f)
-#define IMM116(data) (((data) >> 26) & 0x3f)
-#define AQ(data) (((data) >> 26) & 0x1)
-#define RL(data) (((data) >> 25) & 0x1)
+#define OPCODE(data) (((data) >> 2) & 0x1f)
+#define RD(data) (((data) >> 7) & 0x1f)
+#define RS1(data) (((data) >> 15) & 0x1f)
+#define RS2(data) (((data) >> 20) & 0x1f)
+#define RS3(data) (((data) >> 27) & 0x1f)
+#define FUNCT2(data) (((data) >> 25) & 0x3)
+#define FUNCT3(data) (((data) >> 12) & 0x7)
+#define FUNCT7(data) (((data) >> 25) & 0x7f)
+#define IMM116(data) (((data) >> 26) & 0x3f)
+#define AQ(data) (((data) >> 26) & 0x1)
+#define RL(data) (((data) >> 25) & 0x1)
+#define THIMM2(data) (((data) >> 20) & 0x3f)
+#define THFUNCT12(data) (((data) >> 20) & 0xfff)
+#define THFUNCT5(data) (((data) >> 27) & 0x1f)
static inline insn_t insn_utype_read(uint32_t data)
{
@@ -406,28 +410,51 @@ static inline insn_t insn_ciwtype_read(uint16_t data)
};
}
+static inline insn_t insn_th1type_read(uint32_t data)
+{
+ return (insn_t) {
+ .rs1 = RS1(data),
+ .rs2 = RS2(data),
+ .rd = RD(data),
+ .imm = FUNCT2(data),
+ };
+}
+
+static inline insn_t insn_th2type_read(uint32_t data)
+{
+ return (insn_t) {
+ .rs1 = RS1(data),
+ .rd = RD(data),
+ .imm = IMM116(data),
+ .imm2 = THIMM2(data),
+ };
+}
+
#define RN(r) insn.f ? fpnames[insn.r] : gpnames[insn.r]
#define PRINT_none() snprintf(buff, sizeof(buff), "%s", insn.name); return buff
#define PRINT_rd_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, RN(rd), RN(rs1)); return buff
#define PRINT_rd_rs1_rs2() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s", insn.name, RN(rd), RN(rs1), RN(rs2)); return buff
#define PRINT_rd_rs1_rs2_rs3() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s, %s", insn.name, RN(rd), RN(rs1), RN(rs2), RN(rs3)); return buff
-#define PRINT_rd_rs1_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %d", insn.name, RN(rd), RN(rs1), insn.imm); return buff
+#define PRINT_rd_rs1_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s0x%x", insn.name, RN(rd), RN(rs1), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
#define PRINT_rd_rs1_immx() snprintf(buff, sizeof(buff), "%s\t%s, %s, 0x%x", insn.name, RN(rd), RN(rs1), insn.imm); return buff
-#define PRINT_rd_imm_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %d(%s)", insn.name, RN(rd), insn.imm, gpnames[insn.rs1]); return buff
-#define PRINT_rs2_imm_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %d(%s)", insn.name, RN(rs2), insn.imm, gpnames[insn.rs1]); return buff
-#define PRINT_rd_imm() snprintf(buff, sizeof(buff), "%s\t%s, %d", insn.name, RN(rd), insn.imm); return buff
-#define PRINT_rd_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, pc%+d # 0x%"PRIx64, insn.name, RN(rd), insn.imm, insn.imm+(uint64_t)addr); return buff
-#define PRINT_imm_rel() snprintf(buff, sizeof(buff), "%s\tpc%+d # 0x%"PRIx64, insn.name, insn.imm, insn.imm+(uint64_t)addr); return buff
+#define PRINT_rd_imm_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %s0x%x(%s)", insn.name, RN(rd), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm, gpnames[insn.rs1]); return buff
+#define PRINT_rs2_imm_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %s0x%x(%s)", insn.name, RN(rs2), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm, gpnames[insn.rs1]); return buff
+#define PRINT_rd_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s0x%x", insn.name, RN(rd), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
+#define PRINT_rd_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, pc%s0x%x # 0x%"PRIx64, insn.name, RN(rd), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
+#define PRINT_imm_rel() snprintf(buff, sizeof(buff), "%s\tpc%s0x%x # 0x%"PRIx64, insn.name, insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
#define PRINT_rd_immx() snprintf(buff, sizeof(buff), "%s\t%s, 0x%x", insn.name, RN(rd), insn.imm); return buff
-#define PRINT_rs1_rs2_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %d", insn.name, RN(rs1), RN(rs2), insn.imm); return buff
-#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%+d # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm, insn.imm+(uint64_t)addr); return buff
+#define PRINT_rs1_rs2_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s0x%x", insn.name, RN(rs1), RN(rs2), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
+#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%s0x%x # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
#define PRINT_fd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], fpnames[insn.rs1]); return buff
#define PRINT_xd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, gpnames[insn.rd], fpnames[insn.rs1]); return buff
#define PRINT_fd_xs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], gpnames[insn.rs1]); return buff
#define PRINT_rd_fs1_fs2() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s", insn.name, gpnames[insn.rd], RN(rs1), RN(rs2)); return buff
#define PRINT_rd_rs1_aqrl() snprintf(buff, sizeof(buff), "%s%s%s\t%s, (%s)", insn.name, aq?".aq":"", rl?".rl":"", gpnames[insn.rd], gpnames[insn.rs1]); return buff
#define PRINT_rd_rs1_rs2_aqrl() snprintf(buff, sizeof(buff), "%s%s%s\t%s, %s, (%s)", insn.name, aq?".aq":"", rl?".rl":"", gpnames[insn.rd], gpnames[insn.rs2], gpnames[insn.rs1]); return buff
+#define PRINT_rd_rs1_rs2_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s, %s0x%x", insn.name, RN(rd), RN(rs1), RN(rs2), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
+#define PRINT_rd_rs1_imm1_imm2() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s0x%x, %s0x%x", insn.name, RN(rd), RN(rs1), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm2>=0?"":"-", insn.imm2>=0?insn.imm2:-insn.imm2); return buff
+#define PRINT_rd1_rd2_rs1_imm_4() snprintf(buff, sizeof(buff), "%s\t%s, %s, (%s), %s0x%x, 4", insn.name, RN(rd), RN(rs2), RN(rs1), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
// TODO: display csr name
#define PRINT_rd_csr_rs1() snprintf(buff, sizeof(buff), "%s\t%s, %d, %s", insn.name, RN(rd), insn.csr, RN(rs1)); return buff
@@ -444,35 +471,35 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t copcode = COPCODE(data);
switch (copcode) {
- case 0x0: /* C.ADDI4SPN */
+ case 0x0:
insn = insn_ciwtype_read(data);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.name = "addi";
assert(insn.imm != 0);
PRINT_rd_rs1_imm();
- case 0x1: /* C.FLD */
+ case 0x1:
insn = insn_cltype_read2(data);
insn.name = "fld";
insn.f = true;
PRINT_rd_imm_rs1();
- case 0x2: /* C.LW */
+ case 0x2:
insn = insn_cltype_read(data);
insn.name = "lw";
PRINT_rd_imm_rs1();
- case 0x3: /* C.LD */
+ case 0x3:
insn = insn_cltype_read2(data);
insn.name = "ld";
PRINT_rd_imm_rs1();
- case 0x5: /* C.FSD */
+ case 0x5:
insn = insn_cstype_read(data);
insn.name = "fsd";
insn.f = true;
PRINT_rs2_imm_rs1();
- case 0x6: /* C.SW */
+ case 0x6:
insn = insn_cstype_read2(data);
insn.name = "sw";
PRINT_rd_imm_rs1();
- case 0x7: /* C.SD */
+ case 0x7:
insn = insn_cstype_read(data);
insn.name = "sd";
PRINT_rs2_imm_rs1();
@@ -482,31 +509,31 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t copcode = COPCODE(data);
switch (copcode) {
- case 0x0: /* C.ADDI */
+ case 0x0:
insn = insn_citype_read(data);
insn.rs1 = insn.rd;
insn.name = "addi";
PRINT_rd_rs1_imm();
- case 0x1: /* C.ADDIW */
+ case 0x1:
insn = insn_citype_read(data);
assert(insn.rd != 0);
insn.rs1 = insn.rd;
insn.name = "addiw";
PRINT_rd_rs1_imm();
- case 0x2: /* C.LI */
+ case 0x2:
insn = insn_citype_read(data);
insn.rs1 = 0;
insn.name = "addi";
PRINT_rd_rs1_imm();
case 0x3: {
int32_t rd = RC1(data);
- if (rd == 2) { /* C.ADDI16SP */
+ if (rd == 2) {
insn = insn_citype_read3(data);
assert(insn.imm != 0);
insn.rs1 = insn.rd;
insn.name = "addi";
PRINT_rd_rs1_imm();
- } else { /* C.LUI */
+ } else {
insn = insn_citype_read5(data);
assert(insn.imm != 0);
insn.name = "lui";
@@ -517,9 +544,9 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t cfunct2high = CFUNCT2HIGH(data);
switch (cfunct2high) {
- case 0x0: /* C.SRLI */
- case 0x1: /* C.SRAI */
- case 0x2: { /* C.ANDI */
+ case 0x0:
+ case 0x1:
+ case 0x2: {
insn = insn_cbtype_read2(data);
insn.rs1 = insn.rd;
@@ -543,16 +570,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn.rs1 = insn.rd;
switch (cfunct2low) {
- case 0x0: /* C.SUB */
+ case 0x0:
insn.name = "sub";
break;
- case 0x1: /* C.XOR */
+ case 0x1:
insn.name = "xor";
break;
- case 0x2: /* C.OR */
+ case 0x2:
insn.name = "or";
break;
- case 0x3: /* C.AND */
+ case 0x3:
insn.name = "and";
break;
}
@@ -565,12 +592,14 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn.rs1 = insn.rd;
switch (cfunct2low) {
- case 0x0: /* C.SUBW */
+ case 0x0:
insn.name = "subw";
break;
- case 0x1: /* C.ADDW */
+ case 0x1:
insn.name = "addw";
break;
+ default:
+ goto unknown;
}
break;
}
@@ -579,13 +608,13 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
}
}
}
- case 0x5: /* C.J */
+ case 0x5:
insn = insn_cjtype_read(data);
insn.rd = 0;
insn.name = "jal";
PRINT_rd_imm();
- case 0x6: /* C.BEQZ */
- case 0x7: /* C.BNEZ */
+ case 0x6:
+ case 0x7:
insn = insn_cbtype_read(data);
insn.rs2 = 0;
insn.name = copcode == 0x6 ? "beq" : "bne";
@@ -595,27 +624,27 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
case 0x2: {
uint32_t copcode = COPCODE(data);
switch (copcode) {
- case 0x0: /* C.SLLI */
+ case 0x0:
insn = insn_citype_read(data);
insn.rs1 = insn.rd;
insn.name = "slli";
PRINT_rd_rs1_imm();
- case 0x1: /* C.FLDSP */
+ case 0x1:
insn = insn_citype_read2(data);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.f = true;
insn.name = "fld";
PRINT_rd_imm_rs1();
- case 0x2: /* C.LWSP */
+ case 0x2:
insn = insn_citype_read4(data);
assert(insn.rd != 0);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.name = "lw";
PRINT_rd_imm_rs1();
- case 0x3: /* C.LDSP */
+ case 0x3:
insn = insn_citype_read2(data);
assert(insn.rd != 0);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.name = "ld";
PRINT_rd_imm_rs1();
case 0x4: {
@@ -625,12 +654,12 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
case 0x0: {
insn = insn_crtype_read(data);
- if (insn.rs2 == 0) { /* C.JR */
+ if (insn.rs2 == 0) {
assert(insn.rs1 != 0);
insn.rd = 0;
insn.name = "jalr";
PRINT_rd_imm_rs1();
- } else { /* C.MV */
+ } else {
insn.rd = insn.rs1;
insn.rs1 = 0;
insn.name = "add";
@@ -639,14 +668,14 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
}
case 0x1: {
insn = insn_crtype_read(data);
- if (insn.rs1 == 0 && insn.rs2 == 0) { /* C.EBREAK */
+ if (insn.rs1 == 0 && insn.rs2 == 0) {
insn.name = "ebreak";
PRINT_none();
- } else if (insn.rs2 == 0) { /* C.JALR */
- insn.rd = 1; /* ra */
+ } else if (insn.rs2 == 0) {
+ insn.rd = 1;
insn.name = "jalr";
PRINT_rd_imm_rs1();
- } else { /* C.ADD */
+ } else {
insn.rd = insn.rs1;
insn.name = "add";
PRINT_rd_rs1_rs2();
@@ -654,20 +683,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
}
}
}
- case 0x5: /* C.FSDSP */
+ case 0x5:
insn = insn_csstype_read(data);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.f = true;
insn.name = "fsd";
PRINT_rs2_imm_rs1();
- case 0x6: /* C.SWSP */
+ case 0x6:
insn = insn_csstype_read2(data);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.name = "sw";
PRINT_rs2_imm_rs1();
- case 0x7: /* C.SDSP */
+ case 0x7:
insn = insn_csstype_read(data);
- insn.rs1 = 2; /* sp */
+ insn.rs1 = 2;
insn.name = "sd";
PRINT_rs2_imm_rs1();
}
@@ -680,27 +709,29 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_itype_read(data);
switch (funct3) {
- case 0x0: /* LB */
+ case 0x0:
insn.name = "lb";
break;
- case 0x1: /* LH */
+ case 0x1:
insn.name = "lh";
break;
- case 0x2: /* LW */
+ case 0x2:
insn.name = "lw";
break;
- case 0x3: /* LD */
+ case 0x3:
insn.name = "ld";
break;
- case 0x4: /* LBU */
+ case 0x4:
insn.name = "lbu";
break;
- case 0x5: /* LHU */
+ case 0x5:
insn.name = "lhu";
break;
- case 0x6: /* LWU */
+ case 0x6:
insn.name = "lwu";
break;
+ default:
+ goto unknown;
}
PRINT_rd_imm_rs1();
}
@@ -709,30 +740,118 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_itype_read(data);
switch (funct3) {
- case 0x2: /* FLW */
+ case 0x2:
insn.name = "flw";
insn.f = true;
break;
- case 0x3: /* FLD */
+ case 0x3:
insn.name = "fld";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rd_imm_rs1();
}
+ case 0x2: { /* thead custom-0 */
+ uint32_t funct3 = FUNCT3(data);
+
+ switch (funct3) {
+ case 0x1: {
+ if (RS3(data) == 0x0) {
+ insn = insn_th1type_read(data);
+ insn.name = "th.addsl";
+ PRINT_rd_rs1_rs2_imm();
+ } else if (IMM116(data) == 0x4) {
+ insn = insn_itype_read(data);
+ insn.name = "th.srri";
+ insn.imm &= 0b111111;
+ PRINT_rd_rs1_imm();
+ } else if (IMM116(data) == 0x22) {
+ insn = insn_itype_read(data);
+ insn.name = "th.tst";
+ insn.imm &= 0b111111;
+ PRINT_rd_rs1_imm();
+ } else if (FUNCT7(data) == 0xa) {
+ insn = insn_itype_read(data);
+ insn.name = "th.srriw";
+ insn.imm &= 0b11111;
+ PRINT_rd_rs1_imm();
+ } else if (THFUNCT12(data) == 0x840) {
+ insn = insn_rtype_read(data);
+ insn.name = "th.ff0";
+ PRINT_rd_rs1();
+ } else if (THFUNCT12(data) == 0x860) {
+ insn = insn_rtype_read(data);
+ insn.name = "th.ff1";
+ PRINT_rd_rs1();
+ } else if (THFUNCT12(data) == 0x820) {
+ insn = insn_rtype_read(data);
+ insn.name = "th.rev";
+ PRINT_rd_rs1();
+ } else if (THFUNCT12(data) == 0x900) {
+ insn = insn_rtype_read(data);
+ insn.name = "th.revw";
+ PRINT_rd_rs1();
+ } else if (THFUNCT12(data) == 0x800) {
+ insn = insn_rtype_read(data);
+ insn.name = "th.tstnbz";
+ PRINT_rd_rs1();
+ }
+ goto unknown;
+ }
+ case 0x2: {
+ insn = insn_th2type_read(data);
+ insn.name = "th.ext";
+ PRINT_rd_rs1_imm1_imm2();
+ }
+ case 0x3: {
+ insn = insn_th2type_read(data);
+ insn.name = "th.extu";
+ PRINT_rd_rs1_imm1_imm2();
+ }
+ case 0x4: {
+ switch (THFUNCT5(data)) {
+ case 0x1f: {
+ insn = insn_th1type_read(data);
+ insn.name = "th.ldd";
+ PRINT_rd1_rd2_rs1_imm_4();
+ }
+ default:
+ goto unknown;
+ }
+ }
+ case 0x5: {
+ switch (THFUNCT5(data)) {
+ case 0x1f: {
+ insn = insn_th1type_read(data);
+ insn.name = "th.sdd";
+ PRINT_rd1_rd2_rs1_imm_4();
+ }
+ default:
+ goto unknown;
+ }
+ }
+ default:
+ goto unknown;
+ }
+ break;
+ }
case 0x3: {
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: { /* FENCE */
+ case 0x0: {
insn.name = "fence";
// TODO: handle pred succ
PRINT_none();
}
- case 0x1: { /* FENCE.I */
+ case 0x1: {
insn.name = "fence.i";
PRINT_none();
}
+ default:
+ goto unknown;
}
}
case 0x4: {
@@ -744,7 +863,7 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_itype_read(data);
switch (funct3) {
- case 0x0: /* ADDI */
+ case 0x0:
insn.name = "addi";
if (insn.imm == 0) {
if (insn.rd == 0 && insn.rs1 == 0) {
@@ -758,18 +877,45 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
break;
case 0x1: {
uint32_t imm116 = IMM116(data);
- if (imm116 == 0) { /* SLLI */
+ switch (imm116) {
+ case 0x0:
insn.name = "slli";
+ break;
+ case 0x18: {
+ uint32_t rs2 = RS2(data);
+ switch (rs2) {
+ case 0x0:
+ insn.name = "clz";
+ break;
+ case 0x1:
+ insn.name = "ctz";
+ break;
+ case 0x2:
+ insn.name = "cpop";
+ break;
+ case 0x4:
+ insn.name = "sext.b";
+ break;
+ case 0x5:
+ insn.name = "sext.h";
+ break;
+ default:
+ goto unknown;
+ }
+ PRINT_rd_rs1();
+ }
+ default:
+ goto unknown;
}
break;
}
- case 0x2: /* SLTI */
+ case 0x2:
insn.name = "slti";
break;
- case 0x3: /* SLTIU */
+ case 0x3:
insn.name = "sltiu";
break;
- case 0x4: /* XORI */
+ case 0x4:
insn.name = "xori";
hex = 1;
if (insn.imm == -1) {
@@ -780,22 +926,28 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
case 0x5: {
uint32_t imm116 = IMM116(data);
- if (imm116 == 0x0) { /* SRLI */
+ if (imm116 == 0x0) {
insn.name = "srli";
- } else if (imm116 == 0x10) { /* SRAI */
+ } else if (imm116 == 0x10) {
insn.name = "srai";
- insn.imm&=0b111111;
+ insn.imm &= 0b111111;
+ } else if (imm116 == 0x12) {
+ insn.name = "bexti";
+ insn.imm &= 0b111111;
+ } else if (imm116 == 0x18) {
+ insn.name = "rori";
+ insn.imm &= 0b111111;
} else if (insn.imm==0b011010111000) {
insn.name = "rev8";
PRINT_rd_rs1();
}
break;
}
- case 0x6: /* ORI */
+ case 0x6:
insn.name = "ori";
hex = 1;
break;
- case 0x7: /* ANDI */
+ case 0x7:
insn.name = "andi";
hex = 1;
break;
@@ -812,10 +964,11 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
PRINT_rd_rs1_imm();
}
}
- case 0x5: /* AUIPC */
+ case 0x5: {
insn = insn_utype_read(data);
insn.name = "auipc";
PRINT_rd_imm_rel();
+ }
case 0x6: {
uint32_t funct3 = FUNCT3(data);
uint32_t funct7 = FUNCT7(data);
@@ -823,24 +976,58 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_itype_read(data);
switch (funct3) {
- case 0x0: /* ADDIW */
+ case 0x0:
insn.name = "addiw";
break;
- case 0x1: /* SLLIW */
- assert(funct7 == 0);
- insn.name = "slliw";
+ case 0x1:
+ switch (funct7) {
+ case 0x0:
+ insn.name = "slliw";
+ break;
+ case 0x4:
+ insn.name = "slli.uw";
+ break;
+ case 0x30: {
+ uint32_t rs2 = RS2(data);
+ switch (rs2) {
+ case 0x0:
+ insn.name = "clzw";
+ break;
+ case 0x1:
+ insn.name = "ctzw";
+ break;
+ case 0x2:
+ insn.name = "cpopw";
+ break;
+ default:
+ goto unknown;
+ }
+ PRINT_rd_rs1();
+ }
+ default:
+ goto unknown;
+ }
break;
case 0x5: {
switch (funct7) {
- case 0x0: /* SRLIW */
+ case 0x0:
insn.name = "srliw";
break;
- case 0x20: /* SRAIW */
+ case 0x20:
insn.name = "sraiw";
- insn.imm&=0b111111;
+ insn.imm &= 0b11111;
break;
+ case 0x30:
+ insn.name = "roriw";
+ insn.imm &= 0b11111;
+ break;
+ default:
+ goto unknown;
}
+ break;
}
+ default:
+ goto unknown;
}
PRINT_rd_rs1_imm();
}
@@ -849,18 +1036,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_stype_read(data);
switch (funct3) {
- case 0x0: /* SB */
+ case 0x0:
insn.name = "sb";
break;
- case 0x1: /* SH */
+ case 0x1:
insn.name = "sh";
break;
- case 0x2: /* SW */
+ case 0x2:
insn.name = "sw";
break;
- case 0x3: /* SD */
+ case 0x3:
insn.name = "sd";
break;
+ default:
+ goto unknown;
}
PRINT_rs2_imm_rs1();
}
@@ -869,14 +1058,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_stype_read(data);
switch (funct3) {
- case 0x2: /* FSW */
+ case 0x2:
insn.name = "fsw";
insn.f = true;
break;
- case 0x3: /* FSD */
+ case 0x3:
insn.name = "fsd";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rs2_imm_rs1();
}
@@ -888,22 +1079,24 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
switch(funct3) {
case 0x2:
switch (rs1) {
- case 0x2: /* LR.W */
+ case 0x2:
insn.name = "lr.w";
PRINT_rd_rs1_aqrl();
- case 0x3: /* SC.W */
+ case 0x3:
insn.name = "sc.w";
PRINT_rd_rs1_rs2_aqrl();
}
case 0x3:
switch (rs1) {
- case 0x2: /* LR.D */
+ case 0x2:
insn.name = "lr.d";
PRINT_rd_rs1_aqrl();
- case 0x3: /* SC.D */
+ case 0x3:
insn.name = "sc.d";
PRINT_rd_rs1_rs2_aqrl();
}
+ default:
+ goto unknown;
}
}
case 0xc: {
@@ -915,28 +1108,28 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
switch (funct7) {
case 0x0: {
switch (funct3) {
- case 0x0: /* ADD */
+ case 0x0:
insn.name = "add";
break;
- case 0x1: /* SLL */
+ case 0x1:
insn.name = "sll";
break;
- case 0x2: /* SLT */
+ case 0x2:
insn.name = "slt";
break;
- case 0x3: /* SLTU */
+ case 0x3:
insn.name = "sltu";
break;
- case 0x4: /* XOR */
+ case 0x4:
insn.name = "xor";
break;
- case 0x5: /* SRL */
+ case 0x5:
insn.name = "srl";
break;
- case 0x6: /* OR */
+ case 0x6:
insn.name = "or";
break;
- case 0x7: /* AND */
+ case 0x7:
insn.name = "and";
break;
}
@@ -944,65 +1137,122 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
break;
case 0x1: {
switch (funct3) {
- case 0x0: /* MUL */
+ case 0x0:
insn.name = "mul";
break;
- case 0x1: /* MULH */
+ case 0x1:
insn.name = "mulh";
break;
- case 0x2: /* MULHSU */
+ case 0x2:
insn.name = "mulhsu";
break;
- case 0x3: /* MULHU */
+ case 0x3:
insn.name = "mulhu";
break;
- case 0x4: /* DIV */
+ case 0x4:
insn.name = "div";
break;
- case 0x5: /* DIVU */
+ case 0x5:
insn.name = "divu";
break;
- case 0x6: /* REM */
+ case 0x6:
insn.name = "rem";
break;
- case 0x7: /* REMU */
+ case 0x7:
insn.name = "remu";
break;
}
}
break;
+ case 0x5: {
+ switch (funct3) {
+ case 0x4:
+ insn.name = "min";
+ break;
+ case 0x5:
+ insn.name = "minu";
+ break;
+ case 0x6:
+ insn.name = "max";
+ break;
+ case 0x7:
+ insn.name = "maxu";
+ break;
+ default:
+ goto unknown;
+ }
+ }
+ break;
case 0x10: {
switch (funct3) {
- case 0b010:
+ case 0x2:
insn.name = "sh1add";
break;
- case 0b100:
+ case 0x4:
insn.name = "sh2add";
break;
- case 0b110:
+ case 0x6:
insn.name = "sh3add";
break;
+ default:
+ goto unknown;
}
}
break;
case 0x20: {
switch (funct3) {
- case 0x0: /* SUB */
+ case 0x0:
insn.name = "sub";
break;
- case 0x5: /* SRA */
+ case 0x4:
+ insn.name = "xnor";
+ break;
+ case 0x5:
insn.name = "sra";
break;
+ case 0x6:
+ insn.name = "orn";
+ break;
+ case 0x7:
+ insn.name = "andn";
+ break;
+ default:
+ goto unknown;
}
+ break;
}
- break;
+ case 0x24: {
+ switch (funct3) {
+ case 0x5:
+ insn.name = "bext";
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ }
+ case 0x30: {
+ switch (funct3) {
+ case 0x1:
+ insn.name = "rol";
+ break;
+ case 0x5:
+ insn.name = "ror";
+ break;
+ default:
+ goto unknown;
+ }
+ }
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
- case 0xd: /* LUI */
+ case 0xd: {
insn = insn_utype_read(data);
insn.name = "lui";
PRINT_rd_immx();
+ }
case 0xe: {
insn = insn_rtype_read(data);
@@ -1012,49 +1262,99 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
switch (funct7) {
case 0x0: {
switch (funct3) {
- case 0x0: /* ADDW */
+ case 0x0:
insn.name = "addw";
break;
- case 0x1: /* SLLW */
+ case 0x1:
insn.name = "sllw";
break;
- case 0x5: /* SRLW */
+ case 0x5:
insn.name = "srlw";
break;
+ default:
+ goto unknown;
}
}
break;
case 0x1: {
switch (funct3) {
- case 0x0: /* MULW */
+ case 0x0:
insn.name = "mulw";
break;
- case 0x4: /* DIVW */
+ case 0x4:
insn.name = "divw";
break;
- case 0x5: /* DIVUW */
+ case 0x5:
insn.name = "divuw";
break;
- case 0x6: /* REMW */
+ case 0x6:
insn.name = "remw";
break;
- case 0x7: /* REMUW */
+ case 0x7:
insn.name = "remuw";
break;
+ default:
+ goto unknown;
+ }
+ }
+ break;
+ case 0x4: {
+ switch (funct3) {
+ case 0x0:
+ insn.name = "add.uw";
+ break;
+ case 0x4:
+ assert(insn.rs2 == 0);
+ insn.name = "zext.h";
+ PRINT_rd_rs1();
+ default:
+ goto unknown;
+ }
+ }
+ break;
+ case 0x10: {
+ switch (funct3) {
+ case 0x2:
+ insn.name = "sh1add.uw";
+ break;
+ case 0x4:
+ insn.name = "sh2add.uw";
+ break;
+ case 0x6:
+ insn.name = "sh3add.uw";
+ break;
+ default:
+ goto unknown;
}
}
break;
case 0x20: {
switch (funct3) {
- case 0x0: /* SUBW */
+ case 0x0:
insn.name = "subw";
break;
- case 0x5: /* SRAW */
+ case 0x5:
insn.name = "sraw";
break;
+ default:
+ goto unknown;
}
}
break;
+ case 0x30: {
+ switch (funct3) {
+ case 0x1:
+ insn.name = "rolw";
+ break;
+ case 0x5:
+ insn.name = "rorw";
+ break;
+ default:
+ goto unknown;
+ }
+ }
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1063,14 +1363,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_fprtype_read(data);
switch (funct2) {
- case 0x0: /* FMADD.S */
+ case 0x0:
insn.name = "fmadd.s";
insn.f = true;
break;
- case 0x1: /* FMADD.D */
+ case 0x1:
insn.name = "fmadd.d";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1079,14 +1381,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_fprtype_read(data);
switch (funct2) {
- case 0x0: /* FMSUB.S */
+ case 0x0:
insn.name = "fmsub.s";
insn.f = true;
break;
- case 0x1: /* FMSUB.D */
+ case 0x1:
insn.name = "fmsub.d";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1095,14 +1399,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_fprtype_read(data);
switch (funct2) {
- case 0x0: /* FNMSUB.S */
+ case 0x0:
insn.name = "fnmsub.s";
insn.f = true;
break;
- case 0x1: /* FNMSUB.D */
+ case 0x1:
insn.name = "fnmsub.d";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2_rs3();
}
@@ -1111,14 +1417,16 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_fprtype_read(data);
switch (funct2) {
- case 0x0: /* FNMADD.S */
+ case 0x0:
insn.name = "fnmadd.s";
insn.f = true;
break;
- case 0x1: /* FNMADD.D */
+ case 0x1:
insn.name = "fnmadd.d";
insn.f = true;
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2_rs3();
}
@@ -1128,43 +1436,45 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn = insn_rtype_read(data);
insn.f = true;
switch (funct7) {
- case 0x0: /* FADD.S */
+ case 0x0:
insn.name = "fadd.s";
PRINT_rd_rs1_rs2();
- case 0x1: /* FADD.D */
+ case 0x1:
insn.name = "fadd.d";
PRINT_rd_rs1_rs2();
- case 0x4: /* FSUB.S */
+ case 0x4:
insn.name = "fsub.s";
PRINT_rd_rs1_rs2();
- case 0x5: /* FSUB.D */
+ case 0x5:
insn.name = "fsub.d";
PRINT_rd_rs1_rs2();
- case 0x8: /* FMUL.S */
+ case 0x8:
insn.name = "fmul.s";
PRINT_rd_rs1_rs2();
- case 0x9: /* FMUL.D */
+ case 0x9:
insn.name = "fmul.d";
PRINT_rd_rs1_rs2();
- case 0xc: /* FDIV.S */
+ case 0xc:
insn.name = "fdiv.s";
PRINT_rd_rs1_rs2();
- case 0xd: /* FDIV.D */
+ case 0xd:
insn.name = "fdiv.d";
PRINT_rd_rs1_rs2();
case 0x10: {
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FSGNJ.S */
+ case 0x0:
insn.name = "fsgnj.s";
break;
- case 0x1: /* FSGNJN.S */
+ case 0x1:
insn.name = "fsgnjn.s";
break;
- case 0x2: /* FSGNJX.S */
+ case 0x2:
insn.name = "fsgnjx.s";
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1172,15 +1482,17 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FSGNJ.D */
+ case 0x0:
insn.name = "fsgnj.d";
break;
- case 0x1: /* FSGNJN.D */
+ case 0x1:
insn.name = "fsgnjn.d";
break;
- case 0x2: /* FSGNJX.D */
+ case 0x2:
insn.name = "fsgnjx.d";
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1188,12 +1500,14 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FMIN.S */
+ case 0x0:
insn.name = "fmin.s";
break;
- case 0x1: /* FMAX.S */
+ case 0x1:
insn.name = "fmax.s";
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
@@ -1201,28 +1515,30 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FMIN.D */
+ case 0x0:
insn.name = "fmin.d";
break;
- case 0x1: /* FMAX.D */
+ case 0x1:
insn.name = "fmax.d";
break;
+ default:
+ goto unknown;
}
PRINT_rd_rs1_rs2();
}
- case 0x20: /* FCVT.S.D */
+ case 0x20:
assert(RS2(data) == 1);
insn.name = "fcvt.s.d";
PRINT_fd_fs1();
- case 0x21: /* FCVT.D.S */
+ case 0x21:
assert(RS2(data) == 0);
insn.name = "fcvt.d.s";
PRINT_fd_fs1();
- case 0x2c: /* FSQRT.S */
+ case 0x2c:
assert(insn.rs2 == 0);
insn.name = "fsqrt.s";
PRINT_fd_fs1();
- case 0x2d: /* FSQRT.D */
+ case 0x2d:
assert(insn.rs2 == 0);
insn.name = "fsqrt.d";
PRINT_fd_fs1();
@@ -1230,15 +1546,17 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FLE.S */
+ case 0x0:
insn.name = "fle.s";
break;
- case 0x1: /* FLT.S */
+ case 0x1:
insn.name = "flt.s";
break;
- case 0x2: /* FEQ.S */
+ case 0x2:
insn.name = "feq.s";
break;
+ default:
+ goto unknown;
}
PRINT_rd_fs1_fs2();
}
@@ -1246,15 +1564,17 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FLE.D */
+ case 0x0:
insn.name = "fle.d";
break;
- case 0x1: /* FLT.D */
+ case 0x1:
insn.name = "flt.d";
break;
- case 0x2: /* FEQ.D */
+ case 0x2:
insn.name = "feq.d";
break;
+ default:
+ goto unknown;
}
PRINT_rd_fs1_fs2();
}
@@ -1262,18 +1582,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t rs2 = RS2(data);
switch (rs2) {
- case 0x0: /* FCVT.W.S */
+ case 0x0:
insn.name = "fcvt.w.s";
break;
- case 0x1: /* FCVT.WU.S */
+ case 0x1:
insn.name = "fcvt.wu.s";
break;
- case 0x2: /* FCVT.L.S */
+ case 0x2:
insn.name = "fcvt.l.s";
break;
- case 0x3: /* FCVT.LU.S */
+ case 0x3:
insn.name = "fcvt.lu.s";
break;
+ default:
+ goto unknown;
}
PRINT_xd_fs1();
}
@@ -1281,18 +1603,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t rs2 = RS2(data);
switch (rs2) {
- case 0x0: /* FCVT.W.D */
+ case 0x0:
insn.name = "fcvt.w.d";
break;
- case 0x1: /* FCVT.WU.D */
+ case 0x1:
insn.name = "fcvt.wu.d";
break;
- case 0x2: /* FCVT.L.D */
+ case 0x2:
insn.name = "fcvt.l.d";
break;
- case 0x3: /* FCVT.LU.D */
+ case 0x3:
insn.name = "fcvt.lu.d";
break;
+ default:
+ goto unknown;
}
PRINT_xd_fs1();
}
@@ -1300,18 +1624,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t rs2 = RS2(data);
switch (rs2) {
- case 0x0: /* FCVT.S.W */
+ case 0x0:
insn.name = "fcvt.s.w";
break;
- case 0x1: /* FCVT.S.WU */
+ case 0x1:
insn.name = "fcvt.s.wu";
break;
- case 0x2: /* FCVT.S.L */
+ case 0x2:
insn.name = "fcvt.s.l";
break;
- case 0x3: /* FCVT.S.LU */
+ case 0x3:
insn.name = "fcvt.s.lu";
break;
+ default:
+ goto unknown;
}
PRINT_fd_xs1();
}
@@ -1319,18 +1645,20 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t rs2 = RS2(data);
switch (rs2) {
- case 0x0: /* FCVT.D.W */
+ case 0x0:
insn.name = "fcvt.d.w";
break;
- case 0x1: /* FCVT.D.WU */
+ case 0x1:
insn.name = "fcvt.d.wu";
break;
- case 0x2: /* FCVT.D.L */
+ case 0x2:
insn.name = "fcvt.d.l";
break;
- case 0x3: /* FCVT.D.LU */
+ case 0x3:
insn.name = "fcvt.d.lu";
break;
+ default:
+ goto unknown;
}
PRINT_fd_xs1();
}
@@ -1339,12 +1667,14 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FMV.X.W */
+ case 0x0:
insn.name = "fmv.x.w";
break;
- case 0x1: /* FCLASS.S */
+ case 0x1:
insn.name = "fclass.s";
break;
+ default:
+ goto unknown;
}
PRINT_xd_fs1();
}
@@ -1353,57 +1683,64 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* FMV.X.D */
+ case 0x0:
insn.name = "fmv.x.d";
break;
- case 0x1: /* FCLASS.D */
+ case 0x1:
insn.name = "fclass.d";
break;
+ default:
+ goto unknown;
}
PRINT_xd_fs1();
}
- case 0x78: /* FMV_W_X */
+ case 0x78:
assert(RS2(data) == 0 && FUNCT3(data) == 0);
insn.name = "fmv.w.x";
PRINT_fd_xs1();
- case 0x79: /* FMV_D_X */
+ case 0x79:
assert(RS2(data) == 0 && FUNCT3(data) == 0);
insn.name = "fmv.d.x";
PRINT_fd_xs1();
}
+ default:
+ goto unknown;
}
case 0x18: {
insn = insn_btype_read(data);
uint32_t funct3 = FUNCT3(data);
switch (funct3) {
- case 0x0: /* BEQ */
+ case 0x0:
insn.name = "beq";
break;
- case 0x1: /* BNE */
+ case 0x1:
insn.name = "bne";
break;
- case 0x4: /* BLT */
+ case 0x4:
insn.name = "blt";
break;
- case 0x5: /* BGE */
+ case 0x5:
insn.name = "bge";
break;
- case 0x6: /* BLTU */
+ case 0x6:
insn.name = "bltu";
break;
- case 0x7: /* BGEU */
+ case 0x7:
insn.name = "bgeu";
break;
+ default:
+ goto unknown;
}
PRINT_rs1_rs2_imm_rel();
}
- case 0x19: /* JALR */
+ case 0x19: {
insn = insn_itype_read(data);
insn.name = "jalr";
PRINT_rd_imm_rs1();
- case 0x1b: /* JAL */
+ }
+ case 0x1b: {
insn = insn_jtype_read(data);
if (insn.rd != 0) {
insn.name = "jal";
@@ -1412,8 +1749,9 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
insn.name = "j";
PRINT_imm_rel();
}
+ }
case 0x1c: {
- if (data == 0x73) { /* ECALL */
+ if (data == 0x73) {
insn.name = "ecall";
PRINT_none();
}
@@ -1421,22 +1759,22 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
uint32_t funct3 = FUNCT3(data);
insn = insn_csrtype_read(data);
switch(funct3) {
- case 0x1: /* CSRRW */
+ case 0x1:
insn.name = "csrrw";
PRINT_rd_csr_rs1();
- case 0x2: /* CSRRS */
+ case 0x2:
insn.name = "csrrs";
PRINT_rd_csr_rs1();
- case 0x3: /* CSRRC */
+ case 0x3:
insn.name = "csrrc";
PRINT_rd_csr_rs1();
- case 0x5: /* CSRRWI */
+ case 0x5:
insn.name = "csrrwi";
PRINT_rd_csr_uimm();
- case 0x6: /* CSRRSI */
+ case 0x6:
insn.name = "csrrsi";
PRINT_rd_csr_uimm();
- case 0x7: /* CSRRCI */
+ case 0x7:
insn.name = "csrrci";
PRINT_rd_csr_uimm();
}
@@ -1445,6 +1783,7 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
}
}
+unknown:
snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(data));
return buff;
}
diff --git a/src/elfs/elfload_dump.c b/src/elfs/elfload_dump.c
index d7d11e4..1730967 100644
--- a/src/elfs/elfload_dump.c
+++ b/src/elfs/elfload_dump.c
@@ -45,7 +45,9 @@ const char* DumpSection(Elf64_Shdr *s, char* SST) {
GO(SHT_GNU_ATTRIBUTES);
GO(SHT_GNU_HASH);
GO(SHT_GNU_LIBLIST);
- GO(SHT_CHECKSUM);
+ #ifndef TERMUX
+ GO(SHT_CHECKSUM);
+ #endif
GO(SHT_LOSUNW);
//GO(SHT_SUNW_move);
GO(SHT_SUNW_COMDAT);
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 6a51660..72c2b4f 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -38,6 +38,7 @@
#endif
#include "../emu/x64emu_private.h"
#include "../emu/x64run_private.h"
+#include "../tools/bridge_private.h"
#include "x64tls.h"
void* my__IO_2_1_stderr_ = NULL;
@@ -69,6 +70,9 @@ elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec)
h->globaldefver = NewDefaultVersion();
h->weakdefver = NewDefaultVersion();
h->refcnt = 1;
+
+ h->file = f;
+ h->fileno = fileno(f);
return h;
}
@@ -100,6 +104,8 @@ void FreeElfHeader(elfheader_t** head)
box_free(h->name);
box_free(h->path);
+ if(h->file)
+ fclose(h->file);
box_free(h);
*head = NULL;
@@ -169,201 +175,174 @@ const char* ElfPath(elfheader_t* head)
return NULL;
return head->path;
}
-int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
+#define ALIGN(p) (((p)+box64_pagesize-1)&~(box64_pagesize-1))
+int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
{
uintptr_t offs = 0;
+ loadProtectionFromMap();
+ int log_level = box64_load_addr?LOG_INFO:LOG_DEBUG;
+
+ head->multiblock_n = 0; // count PHEntrie with LOAD
+ uintptr_t max_align = (box64_pagesize-1);
+ for (size_t i=0; i<head->numPHEntries; ++i)
+ if(head->PHEntries[i].p_type == PT_LOAD && head->PHEntries[i].p_flags) {
+ if(max_align < head->PHEntries[i].p_align-1)
+ max_align = head->PHEntries[i].p_align-1;
+ ++head->multiblock_n;
+ }
+
if(!head->vaddr && box64_load_addr) {
- offs = (uintptr_t)find47bitBlockNearHint((void*)box64_load_addr, head->memsz);
- box64_load_addr += head->memsz;
+ offs = (uintptr_t)find47bitBlockNearHint((void*)((box64_load_addr+max_align)&~max_align), head->memsz, max_align);
+ box64_load_addr = offs + head->memsz;
box64_load_addr = (box64_load_addr+0x10ffffffLL)&~0xffffffLL;
}
- int log_level = box64_load_addr?LOG_INFO:LOG_DEBUG;
- if(!offs)
- offs = head->vaddr;
- if(head->vaddr) {
- head->multiblock_n = 0; // count PHEntrie with LOAD
- for (size_t i=0; i<head->numPHEntries; ++i)
- if(head->PHEntries[i].p_type == PT_LOAD && head->PHEntries[i].p_flags)
- ++head->multiblock_n;
- head->multiblock_size = (uint64_t*)box_calloc(head->multiblock_n, sizeof(uint64_t));
- head->multiblock_offs = (uintptr_t*)box_calloc(head->multiblock_n, sizeof(uintptr_t));
- head->multiblock = (void**)box_calloc(head->multiblock_n, sizeof(void*));
- // and now, create all individual blocks
- head->memory = (char*)0xffffffffffffffff;
- int n = 0;
- for (size_t i=0; i<head->numPHEntries; ++i)
- if(head->PHEntries[i].p_type == PT_LOAD && head->PHEntries[i].p_flags) {
- Elf64_Phdr * e = &head->PHEntries[i];
- uintptr_t bstart = e->p_vaddr;
- uint64_t bsize = e->p_memsz;
- uintptr_t balign = e->p_align;
- if (balign) balign = balign-1; else balign = 1;
- if(balign<4095) balign = 4095;
- uintptr_t bend = (bstart + bsize + balign)&(~balign);
- bstart &= ~balign;
- int ok = 0;
- for (int j=0; !ok && j<n; ++j) {
- uintptr_t start = head->multiblock_offs[j];
- uintptr_t end = head->multiblock_offs[j] + head->multiblock_size[j];
- start &= ~balign;
- if( (head->e_type == ET_DYN) ||
- (((bstart>=start) && (bstart<=end+0x1000)) || ((bend>=start) && (bend<=end)) || ((bstart<start) && (bend>end))))
- {
- // merge
- ok = 1;
- if(bstart<start)
- head->multiblock_offs[j] = bstart;
- head->multiblock_size[j] = ((bend>end)?bend:end) - head->multiblock_offs[j];
- --head->multiblock_n;
- }
- }
- if(!ok) {
- head->multiblock_offs[n] = bstart;
- head->multiblock_size[n] = bend - head->multiblock_offs[n];
- ++n;
- }
- }
- head->multiblock_n = n; // might be less in fact
- for (int i=0; i<head->multiblock_n; ++i) {
- printf_log(log_level, "Allocating 0x%lx memory @%p for Elf \"%s\"\n", head->multiblock_size[i], (void*)head->multiblock_offs[i], head->name);
- void* p = mmap((void*)head->multiblock_offs[i], head->multiblock_size[i]
- , PROT_READ | PROT_WRITE | PROT_EXEC
- , MAP_PRIVATE | MAP_ANONYMOUS /*| ((wine_preloaded)?MAP_FIXED:0)*/
- , -1, 0);
- if(p==MAP_FAILED) {
- printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%zx/0x%zx) for elf \"%s\"\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name);
- return 1;
- }
- if(head->multiblock_offs[i] &&( p!=(void*)head->multiblock_offs[i])) {
- if((head->e_type!=ET_DYN)) {
- printf_log(LOG_NONE, "Error, memory map (@%p 0x%zx/0x%zx) for elf \"%s\" allocated @%p\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name, p);
- return 1;
- } else {
- printf_log(LOG_INFO, "Allocated memory is not at hinted %p but %p (size %lx) \"%s\"\n", (void*)head->multiblock_offs[i], p, head->multiblock_size[i], head->name);
- // need to adjust vaddr!
- for (size_t j=0; j<head->numPHEntries; ++j)
- if(head->PHEntries[j].p_type == PT_LOAD) {
- Elf64_Phdr * e = &head->PHEntries[j];
- if(e->p_vaddr>=head->multiblock_offs[j] && e->p_vaddr<(head->multiblock_offs[j]+head->multiblock_size[j])) {
- e->p_vaddr = e->p_vaddr - head->multiblock_offs[j] + (uintptr_t)p;
- if(!head->delta) head->delta = (intptr_t)p - (intptr_t)head->multiblock_offs[j];
- }
- }
- }
- }
- setProtection((uintptr_t)p, head->multiblock_size[i], PROT_READ | PROT_WRITE | PROT_EXEC);
- head->multiblock[i] = p;
- if(p<(void*)head->memory)
- head->memory = (char*)p;
- }
- } else {
- // vaddr is 0, load everything has a One block
- uintptr_t old_offs = offs;
- if(!offs /*&& box64_wine*/)
- offs = (uintptr_t)find47bitBlock(head->memsz); // limit to 47bits...
- printf_log(log_level, "Allocating 0x%zx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name);
- void* p = mmap((void*)offs, head->memsz
- , PROT_READ | PROT_WRITE | PROT_EXEC
- , MAP_PRIVATE | MAP_ANONYMOUS /*| (((offs&&wine_preloaded)?MAP_FIXED:0))*/
- , -1, 0);
- if(offs &&!old_offs && p!=MAP_FAILED && offs!=(uintptr_t)p) {
- // try again
- munmap(p, head->memsz);
- loadProtectionFromMap();
- offs = (uintptr_t)find47bitBlock(head->memsz);
- printf_log(log_level, "New, try. Allocating 0x%zx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name);
- p = mmap((void*)offs, head->memsz
- , PROT_READ | PROT_WRITE | PROT_EXEC
- , MAP_PRIVATE | MAP_ANONYMOUS /*| (((offs&&wine_preloaded)?MAP_FIXED:0))*/
- , -1, 0);
- }
- if(p==MAP_FAILED) {
- printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%zx/0x%zx) for elf \"%s\"\n", (void*)offs, head->memsz, head->align, head->name);
- return 1;
+ if(!offs && !head->vaddr)
+ offs = (uintptr_t)find47bitBlockElf(head->memsz, mainbin, max_align); // limit to 47bits...
+ #if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
+ // Will not try anything smart on pagesize != 4k....
+ void* image = mmap64((void*)(head->vaddr?head->vaddr:offs), head->memsz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ #else // PAGE4K
+ // prereserve the whole elf image, without populating
+ void* image = mmap64((void*)(head->vaddr?head->vaddr:offs), head->memsz, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+ if(image!=MAP_FAILED && head->vaddr && image!=(void*)offs && (((uintptr_t)image)&max_align)) {
+ munmap(image, head->memsz);
+ image = mmap64(find47bitBlockElf(head->memsz, mainbin, max_align), head->memsz, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+ }
+ #endif
+ if(image!=MAP_FAILED && !head->vaddr && image!=(void*)offs) {
+ printf_log(LOG_INFO, "Mmap64 for (@%p 0x%zx) for elf \"%s\" returned %p instead\n", (void*)(head->vaddr?head->vaddr:offs), head->memsz, head->name, image);
+ offs = (uintptr_t)image;
+ }
+ if(image==MAP_FAILED || image!=(void*)(head->vaddr?head->vaddr:offs)) {
+ printf_log(LOG_NONE, "%s cannot create memory map (@%p 0x%zx) for elf \"%s\"", (image==MAP_FAILED)?"Error:":"Warning:", (void*)(head->vaddr?head->vaddr:offs), head->memsz, head->name);
+ if(image==MAP_FAILED) {
+ printf_log(LOG_NONE, " error=%d/%s\n", errno, strerror(errno));
+ } else {
+ printf_log(LOG_NONE, " got %p\n", image);
}
- if(offs && (p!=(void*)offs) && (head->e_type!=ET_DYN)) {
- printf_log(LOG_NONE, "Error, memory map (@%p 0x%zx/0x%zx) for elf \"%s\" allocated @%p\n", (void*)offs, head->memsz, head->align, head->name, p);
+ if(image==MAP_FAILED)
return 1;
- }
- setProtection((uintptr_t)p, head->memsz, PROT_READ | PROT_WRITE | PROT_EXEC);
- head->memory = p;
- memset(p, 0, head->memsz);
- head->delta = (intptr_t)p - (intptr_t)head->vaddr;
- printf_log(log_level, "Got %p (delta=%p)\n", p, (void*)head->delta);
-
- head->multiblock_n = 1;
- head->multiblock_size = (uint64_t*)box_calloc(head->multiblock_n, sizeof(uint64_t));
- head->multiblock_offs = (uintptr_t*)box_calloc(head->multiblock_n, sizeof(uintptr_t));
- head->multiblock = (void**)box_calloc(head->multiblock_n, sizeof(void*));
- head->multiblock_size[0] = head->memsz;
- head->multiblock_offs[0] = (uintptr_t)p;
- head->multiblock[0] = p;
+ offs = (uintptr_t)image-head->vaddr;
}
+ printf_log(log_level, "Pre-allocated 0x%zx byte at %p for %s\n", head->memsz, image, head->name);
+ head->delta = offs;
+ printf_log(log_level, "Delta of %p (vaddr=%p) for Elf \"%s\"\n", (void*)offs, (void*)head->vaddr, head->name);
+
+ head->image = image;
+ #if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
+ setProtection_elf((uintptr_t)image, head->memsz, PROT_READ|PROT_WRITE|PROT_EXEC);
+ #else
+ setProtection_elf((uintptr_t)image, head->memsz, 0);
+ #endif
+ head->multiblocks = (multiblock_t*)box_calloc(head->multiblock_n, sizeof(multiblock_t));
head->tlsbase = AddTLSPartition(context, head->tlssize);
-
- return 0;
-}
-
-void FreeElfMemory(elfheader_t* head)
-{
- if(head->multiblock_n) {
- for(int i=0; i<head->multiblock_n; ++i) {
-#ifdef DYNAREC
- dynarec_log(LOG_INFO, "Free DynaBlocks for %s\n", head->path);
- if(box64_dynarec) {
- cleanDBFromAddressRange((uintptr_t)head->multiblock[i], head->multiblock_size[i], 1);
- freeProtection((uintptr_t)head->multiblock[i], head->multiblock_size[i]);
- }
-#endif
- munmap(head->multiblock[i], head->multiblock_size[i]);
- }
- box_free(head->multiblock);
- box_free(head->multiblock_size);
- box_free(head->multiblock_offs);
- }
-}
-
-int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
-{
+ // and now, create all individual blocks
+ head->memory = (char*)0xffffffffffffffff;
+ int n = 0;
for (size_t i=0; i<head->numPHEntries; ++i) {
- if(head->PHEntries[i].p_type == PT_LOAD) {
+ if(head->PHEntries[i].p_type == PT_LOAD && head->PHEntries[i].p_flags) {
Elf64_Phdr * e = &head->PHEntries[i];
- char* dest = (char*)e->p_paddr + head->delta;
- printf_log(LOG_DEBUG, "MMap block #%zu @%p offset=%p (0x%zx/0x%zx)\n", i, dest, (void*)e->p_offset, e->p_filesz, e->p_memsz);
- void* p = (void*)-1;
- if(e->p_memsz==e->p_filesz && !(e->p_align&(box64_pagesize-1))) {
- printf_log(LOG_DEBUG, "MMap block #%zu @%p offset=%p (0x%zx/0x%zx, flags:0x%x)\n", i, dest, (void*)e->p_offset, e->p_filesz, e->p_memsz, e->p_flags);
- p = mmap(dest, e->p_filesz, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fileno(f), e->p_offset);
+
+ head->multiblocks[n].flags = e->p_flags;
+ head->multiblocks[n].offs = e->p_offset;
+ head->multiblocks[n].paddr = e->p_paddr + offs;
+ head->multiblocks[n].size = e->p_filesz;
+ head->multiblocks[n].align = e->p_align;
+ uint8_t prot = ((e->p_flags & PF_R)?PROT_READ:0)|((e->p_flags & PF_W)?PROT_WRITE:0)|((e->p_flags & PF_X)?PROT_EXEC:0);
+ #if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
+ head->multiblocks[n].p = NULL;
+ if(e->p_filesz) {
+ fseeko64(head->file, head->multiblocks[n].offs, SEEK_SET);
+ if(fread((void*)head->multiblocks[n].paddr, head->multiblocks[n].size, 1, head->file)!=1) {
+ printf_log(LOG_NONE, "Cannot read elf block (@%p 0x%zx) for elf \"%s\"\n", (void*)head->multiblocks[n].offs, head->multiblocks[n].asize, head->name);
+ return 1;
+ }
+ }
+ #else //PAGE4K
+ // check if alignment is correct
+ uintptr_t balign = head->multiblocks[n].align-1;
+ if(balign<(box64_pagesize-1)) balign = (box64_pagesize-1);
+ head->multiblocks[n].asize = ALIGN(e->p_memsz+(e->p_paddr&balign));
+ int try_mmap = 1;
+ if(e->p_paddr&balign)
+ try_mmap = 0;
+ if(e->p_offset&(box64_pagesize-1))
+ try_mmap = 0;
+ if(e->p_memsz-e->p_filesz>(box64_pagesize-1))
+ try_mmap = 0;
+ if(!e->p_filesz)
+ try_mmap = 0;
+ if(try_mmap) {
+ printf_log(log_level, "Mmaping 0x%lx(0x%lx) bytes @%p for Elf \"%s\"\n", head->multiblocks[n].size, head->multiblocks[n].asize, (void*)head->multiblocks[n].paddr, head->name);
+ void* p = mmap64(
+ (void*)head->multiblocks[n].paddr,
+ head->multiblocks[n].size,
+ prot,
+ MAP_PRIVATE|MAP_FIXED, //((prot&PROT_WRITE)?MAP_SHARED:MAP_PRIVATE)|MAP_FIXED,
+ head->fileno,
+ e->p_offset
+ );
+ if(p==MAP_FAILED || p!=(void*)head->multiblocks[n].paddr) {
+ try_mmap = 0;
+ printf_log(log_level, "Mapping failed, using regular mmap+read");
+ } else {
+ setProtection_elf((uintptr_t)p, head->multiblocks[n].asize, prot);
+ head->multiblocks[n].p = p;
+
+ }
}
- if(p!=dest) {
- printf_log(LOG_DEBUG, "Loading block #%zu %p (0x%zx/0x%zx)\n",i, dest, e->p_filesz, e->p_memsz);
- fseeko64(f, e->p_offset, SEEK_SET);
+ if(!try_mmap) {
+ uintptr_t paddr = head->multiblocks[n].paddr&~balign;
+ size_t asize = head->multiblocks[n].asize;
+ printf_log(log_level, "Allocating 0x%zx (0x%zx) bytes @%p, will read 0x%zx @%p for Elf \"%s\"\n", asize, e->p_memsz, (void*)paddr, e->p_filesz, (void*)head->multiblocks[n].paddr, head->name);
+ void* p = mmap64(
+ (void*)paddr,
+ asize,
+ prot|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
+ -1,
+ 0
+ );
+ if(p==MAP_FAILED || p!=(void*)paddr) {
+ printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%zx/0x%zx) for elf \"%s\"", (void*)paddr, asize, balign, head->name);
+ if(p==MAP_FAILED) {
+ printf_log(LOG_NONE, " error=%d/%s\n", errno, strerror(errno));
+ } else {
+ printf_log(LOG_NONE, " got %p\n", p);
+ }
+ return 1;
+ }
+ setProtection_elf((uintptr_t)p, asize, prot);
+ head->multiblocks[n].p = p;
if(e->p_filesz) {
- if(fread(dest, e->p_filesz, 1, f)!=1) {
- printf_log(LOG_NONE, "Fail to read PT_LOAD part #%zu (size=%zd)\n", i, e->p_filesz);
+ fseeko64(head->file, head->multiblocks[n].offs, SEEK_SET);
+ if(fread((void*)head->multiblocks[n].paddr, head->multiblocks[n].size, 1, head->file)!=1) {
+ printf_log(LOG_NONE, "Cannot read elf block (@%p 0x%zx/0x%zx) for elf \"%s\"\n", (void*)head->multiblocks[n].offs, head->multiblocks[n].asize, balign, head->name);
return 1;
}
}
+ if(!(prot&PROT_WRITE))
+ mprotect((void*)paddr, asize, prot);
}
+ #endif //PAGE4K
#ifdef DYNAREC
if(box64_dynarec && (e->p_flags & PF_X)) {
- dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", dest, (void*)e->p_memsz);
- addDBFromAddressRange((uintptr_t)dest, e->p_memsz);
+ dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", head->multiblocks[n].p, (void*)head->multiblocks[n].asize);
+ addDBFromAddressRange((uintptr_t)head->multiblocks[n].p, head->multiblocks[n].asize);
}
#endif
-
- // zero'd difference between filesz and memsz
- /*if(e->p_filesz != e->p_memsz)
- memset(dest+e->p_filesz, 0, e->p_memsz - e->p_filesz);*/ //block is already 0'd at creation
+ if((uintptr_t)head->memory>(uintptr_t)head->multiblocks[n].p)
+ head->memory = (char*)head->multiblocks[n].p;
+ ++n;
}
if(head->PHEntries[i].p_type == PT_TLS) {
Elf64_Phdr * e = &head->PHEntries[i];
char* dest = (char*)(context->tlsdata+context->tlssize+head->tlsbase);
printf_log(LOG_DEBUG, "Loading TLS block #%zu @%p (0x%zx/0x%zx)\n", i, dest, e->p_filesz, e->p_memsz);
if(e->p_filesz) {
- fseeko64(f, e->p_offset, SEEK_SET);
- if(fread(dest, e->p_filesz, 1, f)!=1) {
+ fseeko64(head->file, e->p_offset, SEEK_SET);
+ if(fread(dest, e->p_filesz, 1, head->file)!=1) {
printf_log(LOG_NONE, "Fail to read PT_TLS part #%zu (size=%zd)\n", i, e->p_filesz);
return 1;
}
@@ -373,9 +352,34 @@ int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
memset(dest+e->p_filesz, 0, e->p_memsz - e->p_filesz);
}
}
+
+ // can close the elf file now!
+ fclose(head->file);
+ head->file = NULL;
+ head->fileno = -1;
+
return 0;
}
+void FreeElfMemory(elfheader_t* head)
+{
+ if(head->multiblock_n) {
+#ifdef DYNAREC
+ for(int i=0; i<head->multiblock_n; ++i) {
+ dynarec_log(LOG_INFO, "Free DynaBlocks for %s\n", head->path);
+ if(box64_dynarec)
+ cleanDBFromAddressRange((uintptr_t)head->multiblocks[i].p, head->multiblocks[i].size, 1);
+ freeProtection((uintptr_t)head->multiblocks[i].p, head->multiblocks[i].asize);
+ }
+#endif
+ box_free(head->multiblocks);
+ }
+ // we only need to free the overall mmap, no need to free individual part as they are inside the big one
+ if(head->image && head->memsz)
+ munmap(head->image, head->memsz);
+ freeProtection((uintptr_t)head->image, head->memsz);
+}
+
int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded)
{
if(!verneeded || !head)
@@ -393,39 +397,6 @@ int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verne
return 1;
}
-int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
-{
- (void)context;
-
- for (size_t i=0; i<head->numPHEntries; ++i) {
- if(head->PHEntries[i].p_type == PT_LOAD) {
- Elf64_Phdr * e = &head->PHEntries[i];
- char* dest = (char*)e->p_paddr + head->delta;
- printf_log(LOG_DEBUG, "Re-loading block #%zu @%p (0x%zx/0x%zx)\n", i, dest, e->p_filesz, e->p_memsz);
- int ret = fseeko64(f, e->p_offset, SEEK_SET);
- if(ret==-1) {printf_log(LOG_NONE, "Fail to (re)seek PT_LOAD part #%zu (offset=%ld, errno=%d/%s)\n", i, e->p_offset, errno, strerror(errno)); return 1;}
- #ifdef DYNAREC
- cleanDBFromAddressRange((uintptr_t)dest, e->p_memsz, 0);
- #endif
- uint32_t page_offset = (uintptr_t)dest & (box64_pagesize - 1);
- mprotect(dest - page_offset, e->p_memsz + page_offset, PROT_READ | PROT_WRITE | PROT_EXEC);
- setProtection((uintptr_t)dest - page_offset, e->p_memsz + page_offset, PROT_READ | PROT_WRITE | PROT_EXEC);
- if(e->p_filesz) {
- ssize_t r = -1;
- if((r=fread(dest, e->p_filesz, 1, f))!=1) {
- printf_log(LOG_NONE, "Fail to (re)read PT_LOAD part #%zu (dest=%p, size=%zd, return=%zd, feof=%d/ferror=%d/%s)\n", i, dest, e->p_filesz, r, feof(f), ferror(f), strerror(ferror(f)));
- return 1;
- }
- }
- // zero'd difference between filesz and memsz
- if(e->p_filesz != e->p_memsz)
- memset(dest+e->p_filesz, 0, e->p_memsz - e->p_filesz);
- }
- }
- // TLS data are just a copy, no need to re-load it
- return 0;
-}
-
int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername)
{
if(!h)
@@ -471,7 +442,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
if(version!=-1) version &=0x7fff;
const char* vername = GetSymbolVersion(head, version);
const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname);
- const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
+ const char* weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
if(bind==STB_LOCAL) {
if(!symname || !symname[0]) {
offs = sym->st_value + head->delta;
@@ -494,14 +465,14 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
if(!offs && !end) {
if(!offs && !end && local_maplib)
GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
- if(!offs && !end && local_maplib)
+ if(!offs && !end)
GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
} else {
if(!offs && !end) {
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
- if(!offs && !end && local_maplib)
+ if(!offs && !end)
GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
}
@@ -539,10 +510,10 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
*p = globoffs;
} else {
// Look for same symbol already loaded but not in self (so no need for local_maplib here)
- if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) {
+ /*if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) {
offs = globoffs;
end = globend;
- }
+ }*/
if (!offs) {
if(strcmp(symname, "__gmon_start__") && strcmp(symname, "data_start") && strcmp(symname, "__data_start") && strcmp(symname, "collector_func_load"))
printf_log(LOG_NONE, "%s: Global Symbol %s (ver=%d/%s) not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, version, vername?vername:"(none)", p, *(void**)p, head->name);
@@ -676,7 +647,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
weakdefver = old_weakdefver;
} else {
old_globdefver = globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname);
- old_weakdefver = weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
+ old_weakdefver = weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
}
if(bind==STB_LOCAL) {
if(!symname || !symname[0]) {
@@ -715,9 +686,10 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
offs = old_offs;
end = old_end;
} else {
- GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+ if(!offs && !end)
+ GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
}
}
@@ -787,10 +759,10 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
*p = globoffs;
} else {
// Look for same symbol already loaded but not in self (so no need for local_maplib here)
- if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) {
+ /*if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) {
offs = globoffs;
end = globend;
- }
+ }*/
if (!offs) {
if(strcmp(symname, "__gmon_start__") && strcmp(symname, "data_start") && strcmp(symname, "__data_start") && strcmp(symname, "collector_func_load"))
printf_log((bind==STB_WEAK)?LOG_INFO:LOG_NONE, "%s: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, p, *(void**)p, head->name);
@@ -1060,6 +1032,10 @@ uintptr_t GetLastByte(elfheader_t* h)
return (uintptr_t)h->memory/* + h->delta*/ + h->memsz;
}
+#ifndef STB_GNU_UNIQUE
+#define STB_GNU_UNIQUE 10
+#endif
+
void checkHookedSymbols(elfheader_t* h); // in mallochook.c
void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h)
{
@@ -1273,8 +1249,8 @@ void RefreshElfTLS(elfheader_t* h)
char* dest = (char*)(my_context->tlsdata+my_context->tlssize+h->tlsbase);
printf_dump(LOG_DEBUG, "Refreshing main TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlsfilesize);
memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize);
- tlsdatasize_t* ptr;
- if ((ptr = (tlsdatasize_t*)pthread_getspecific(my_context->tlskey)) != NULL) {
+ if (pthread_getspecific(my_context->tlskey)) {
+ tlsdatasize_t* ptr = getTLSData(my_context);
// refresh in tlsdata too
dest = (char*)(ptr->data+h->tlsbase);
printf_dump(LOG_DEBUG, "Refreshing active TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlssize-h->tlsfilesize);
@@ -1328,16 +1304,15 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu)
// reset Segs Cache
memset(emu->segs_serial, 0, sizeof(emu->segs_serial));
uintptr_t p = h->initentry + h->delta;
- box64context_t* context = GetEmuContext(emu);
// Refresh no-file part of TLS in case default value changed
RefreshElfTLS(h);
// check if in deferredInit
- if(context->deferredInit) {
- if(context->deferredInitSz==context->deferredInitCap) {
- context->deferredInitCap += 4;
- context->deferredInitList = (elfheader_t**)box_realloc(context->deferredInitList, context->deferredInitCap*sizeof(elfheader_t*));
+ if(my_context->deferredInit) {
+ if(my_context->deferredInitSz==my_context->deferredInitCap) {
+ my_context->deferredInitCap += 4;
+ my_context->deferredInitList = (elfheader_t**)box_realloc(my_context->deferredInitList, my_context->deferredInitCap*sizeof(elfheader_t*));
}
- context->deferredInitList[context->deferredInitSz++] = h;
+ my_context->deferredInitList[my_context->deferredInitSz++] = h;
return;
}
h->init_done = 1;
@@ -1349,14 +1324,14 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu)
}
printf_dump(LOG_DEBUG, "Calling Init for %s @%p\n", ElfName(h), (void*)p);
if(h->initentry)
- RunFunctionWithEmu(emu, 0, p, 3, context->argc, context->argv, context->envv);
+ RunFunctionWithEmu(emu, 0, p, 3, my_context->argc, my_context->argv, my_context->envv);
printf_dump(LOG_DEBUG, "Done Init for %s\n", ElfName(h));
// and check init array now
Elf64_Addr *addr = (Elf64_Addr*)(h->initarray + h->delta);
for (size_t i=0; i<h->initarray_sz; ++i) {
if(addr[i]) {
printf_dump(LOG_DEBUG, "Calling Init[%zu] for %s @%p\n", i, ElfName(h), (void*)addr[i]);
- RunFunctionWithEmu(emu, 0, (uintptr_t)addr[i], 3, context->argc, context->argv, context->envv);
+ RunFunctionWithEmu(emu, 0, (uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv);
}
}
@@ -1391,6 +1366,10 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu)
if(!h || h->fini_done || !h->init_done)
return;
h->fini_done = 1;
+#ifdef ANDROID
+ // TODO: Fix .fini_array on Android
+ printf_log(LOG_DEBUG, "Android does not support Fini for %s\n", ElfName(h));
+#else
// first check fini array
Elf64_Addr *addr = (Elf64_Addr*)(h->finiarray + h->delta);
for (int i=h->finiarray_sz-1; i>=0; --i) {
@@ -1405,6 +1384,7 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu)
}
h->init_done = 0; // can be re-inited again...
return;
+#endif
}
uintptr_t GetElfInit(elfheader_t* h)
@@ -1418,7 +1398,7 @@ uintptr_t GetElfFini(elfheader_t* h)
void* GetBaseAddress(elfheader_t* h)
{
- return h->memory;
+ return h->image;
}
void* GetElfDelta(elfheader_t* h)
@@ -1435,13 +1415,20 @@ int IsAddressInElfSpace(const elfheader_t* h, uintptr_t addr)
{
if(!h)
return 0;
+ #if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
+ uintptr_t base = (uintptr_t)h->image;
+ uintptr_t end = base+h->memsz;
+ if(base && addr>=base && addr<=end)
+ return 1;
+ #else //PAGE4K
for(int i=0; i<h->multiblock_n; ++i) {
- uintptr_t base = h->multiblock_offs[i];
- uintptr_t end = h->multiblock_offs[i] + h->multiblock_size[i] - 1;
- if(addr>=base && addr<=end)
+ uintptr_t base = (uintptr_t)h->multiblocks[i].p;
+ uintptr_t end = (uintptr_t)h->multiblocks[i].p + h->multiblocks[i].asize - 1;
+ if(base && addr>=base && addr<=end)
return 1;
}
+ #endif //PAGE4K
return 0;
}
elfheader_t* FindElfAddress(box64context_t *context, uintptr_t addr)
@@ -1461,22 +1448,23 @@ const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uin
const char* ret = NULL;
uintptr_t s = 0;
uint64_t size = 0;
- #ifdef HAVE_TRACE
+ if((uintptr_t)p<0x10000)
+ return ret;
if(!h) {
if(getProtection((uintptr_t)p)&(PROT_READ)) {
- if(*(uint8_t*)(p)==0xCC && *(uint8_t*)(p+1)=='S' && *(uint8_t*)(p+2)=='C') {
- ret = getBridgeName(*(void**)(p+3+8));
+ uintptr_t adj_p = ((uintptr_t)p)&~(sizeof(onebridge_t));
+ if(*(uint8_t*)(adj_p)==0xCC && *(uint8_t*)(adj_p+1)=='S' && *(uint8_t*)(adj_p+2)=='C') {
+ ret = getBridgeName((void*)adj_p);
if(ret) {
if(start)
- *start = (uintptr_t)p;
+ *start = (uintptr_t)adj_p;
if(sz)
- *sz = 32;
+ *sz = sizeof(onebridge_t);
}
}
}
return ret;
}
- #endif
if(!h || h->fini_done)
return ret;
diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h
index d2bc255..ed151b3 100644
--- a/src/elfs/elfloader_private.h
+++ b/src/elfs/elfloader_private.h
@@ -9,7 +9,17 @@ typedef struct kh_defaultversion_s kh_defaultversion_t;
#include <elf.h>
#include "elfloader.h"
-struct elfheader_s {
+typedef struct multiblock_s {
+ void* p;
+ uintptr_t offs;
+ uintptr_t paddr;
+ uintptr_t align;
+ uint64_t size;
+ uint64_t asize;
+ uint8_t flags;
+} multiblock_t;
+
+typedef struct elfheader_s {
char* name;
char* path; // Resolved path to file
char* soname; // soname of the elf
@@ -39,6 +49,7 @@ struct elfheader_s {
uint32_t flags;
intptr_t delta; // should be 0
+ void* image;
uintptr_t entrypoint;
uintptr_t initentry;
@@ -90,20 +101,21 @@ struct elfheader_s {
int malloc_hook_2; // this elf hook malloc, hacking it
char* memory; // char* and not void* to allow math on memory pointer
- void** multiblock;
- uintptr_t* multiblock_offs;
- uint64_t* multiblock_size;
+ multiblock_t* multiblocks;
int multiblock_n;
library_t *lib; // attached lib (exept on main elf)
needed_libs_t* needed;
+ FILE* file;
+ int fileno;
+
kh_mapsymbols_t *mapsymbols;
kh_mapsymbols_t *weaksymbols;
kh_mapsymbols_t *localsymbols;
kh_defaultversion_t *globaldefver; // the global default version for symbols (the XXX@@vvvv of symbols)
kh_defaultversion_t *weakdefver; // the weak default version for symbols (the XXX@@vvvv of symbols)
-};
+} elfheader_t;
#define R_X86_64_NONE 0 /* No reloc */
#define R_X86_64_64 1 /* Direct 64 bit */
diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c
index 1701378..994581f 100644
--- a/src/elfs/elfparser.c
+++ b/src/elfs/elfparser.c
@@ -247,8 +247,10 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
printf_dump(LOG_DEBUG, "The DT_INIT_ARRAYSZ is %zu\n", h->initarray_sz);
break;
case DT_PREINIT_ARRAYSZ:
- if(val)
- printf_log(LOG_NONE, "Warning, PreInit Array (size=%d) present and ignored!\n", val);
+ #ifndef ANDROID
+ if(val)
+ printf_log(LOG_NONE, "Warning, PreInit Array (size=%d) present and ignored!\n", val);
+ #endif
break;
case DT_FINI: // Exit hook
h->finientry = ptr;
@@ -466,4 +468,19 @@ const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx)
}
}
return NULL;
-} \ No newline at end of file
+}
+
+int GetNeededVersionForLib(elfheader_t* h, const char* libname, const char* ver)
+{
+ if(!libname || !ver)
+ return 0;
+ int n = GetNeededVersionCnt(h, libname);
+ if(!n)
+ return 0;
+ for(int i=0; i<n; ++i) {
+ const char* vername = GetNeededVersionString(h, libname, i);
+ if(vername && !strcmp(ver, vername))
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/emu/x64compstrings.c b/src/emu/x64compstrings.c
new file mode 100644
index 0000000..d61a516
--- /dev/null
+++ b/src/emu/x64compstrings.c
@@ -0,0 +1,120 @@
+#include <stdint.h>
+
+#include "box64stack.h"
+#include "x64emu.h"
+#include "x64run_private.h"
+#include "x64emu_private.h"
+#include "x64compstrings.h"
+
+static int overrideIfDataInvalid(sse_regs_t* mem, int lmem, sse_regs_t* reg, int lreg, int j, int i, int imm8)
+{
+ int valid1 = (i<lreg);
+ int valid2 = (j<lmem);
+ if(!valid1 && !valid2)
+ switch((imm8>>2)&3) {
+ case 0b00:
+ case 0b01: return 0;
+ case 0b10:
+ case 0b11: return 1;
+ }
+ if(!valid1 && valid2)
+ switch((imm8>>2)&3) {
+ case 0b00:
+ case 0b01:
+ case 0b10: return 0;
+ case 0b11: return 1;
+ }
+ if(valid1 && !valid2)
+ return 0;
+ switch((imm8>>2)&3) {
+ case 0b01: // range
+ switch (imm8&3) {
+ case 0b00: // ub
+ return (i&1)?((reg->ub[i]>=mem->ub[j])):((reg->ub[i]<=mem->ub[j]));
+ case 0b01: // uw
+ return (i&1)?((reg->uw[i]>=mem->uw[j])):((reg->uw[i]<=mem->uw[j]));
+ case 0b10: // sb
+ return (i&1)?((reg->sb[i]>=mem->sb[j])):((reg->sb[i]<=mem->sb[j]));
+ case 0b11: // sw
+ return (i&1)?((reg->sw[i]>=mem->sw[j])):((reg->sw[i]<=mem->sw[j]));
+ }
+ break;
+ default: // the others
+ switch (imm8&1) {
+ case 0: // byte
+ return (reg->ub[i] == mem->ub[j]);
+ case 1: // word
+ return (reg->uw[i] == mem->uw[j]);
+ }
+ }
+}
+
+uint32_t sse42_compare_string_explicit_len(x64emu_t* emu, sse_regs_t* mem, int lmem, sse_regs_t* reg, int lreg, uint8_t imm8)
+{
+ // get number of packed byte/word
+ int n_packed = (imm8&1)?8:16;
+ if(lreg<0) lreg = -lreg;
+ if(lmem<0) lmem = -lmem;
+ if(lreg>n_packed) lreg = n_packed;
+ if(lmem>n_packed) lmem = n_packed;
+ // aggregate to intres1
+ uint32_t intres1 = 0;
+ switch((imm8>>2)&3) {
+ case 0b00: //Equal any
+ for(int j=0; j<n_packed; ++j)
+ for(int i=0; i<n_packed; ++i) {
+ intres1 |= overrideIfDataInvalid(mem, lmem, reg, lreg, j, i, imm8)<<j;
+ }
+ break;
+ case 0b01: // Range
+ for(int j=0; j<n_packed; ++j)
+ for(int i=0; i<n_packed; i+=2) {
+ intres1 |= (overrideIfDataInvalid(mem, lmem, reg, lreg, j, i, imm8) & overrideIfDataInvalid(mem, lmem, reg, lreg, j, i+1, imm8))<<j;
+ }
+ break;
+ case 0b10: // Equal each
+ for(int i=0; i<n_packed; ++i) {
+ intres1 |= overrideIfDataInvalid(mem, lmem, reg, lreg, i, i, imm8)<<i;
+ }
+ break;
+ case 0b11: // Equal ordered
+ intres1 = (1<<n_packed)-1;
+ for(int j=0; j<n_packed; ++j)
+ for(int i=0; i<n_packed-j; ++i) {
+ int k = i+j;
+ intres1 &= (((1<<n_packed)-1)^(1<<j)) | overrideIfDataInvalid(mem, lmem, reg, lreg, k, i, imm8)<<j;
+ }
+ break;
+ }
+ // build intres2
+ uint32_t intres2 = intres1;
+ switch((imm8>>4)&3) {
+ case 0b01: intres2 ^= ((1<<n_packed)-1); break;
+ case 0b11: intres2 ^= ((1<<lmem)-1); break;
+ }
+ // and now set the flags
+ RESET_FLAGS(emu);
+ CONDITIONAL_SET_FLAG(intres2, F_CF);
+ CONDITIONAL_SET_FLAG(lmem<n_packed, F_ZF);
+ CONDITIONAL_SET_FLAG(lreg<n_packed, F_SF);
+ CONDITIONAL_SET_FLAG(intres2&1, F_OF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+
+ return intres2;
+}
+
+uint32_t sse42_compare_string_implicit_len(x64emu_t* emu, sse_regs_t* mem, sse_regs_t* reg, uint8_t imm8)
+{
+ int lmem = 0;
+ int lreg = 0;
+ // get lmem and lreg
+ if(imm8&1) {
+ while(lmem<8 && mem->uw[lmem]) ++lmem;
+ while(lreg<8 && reg->uw[lreg]) ++lreg;
+ } else {
+ while(lmem<16 && mem->ub[lmem]) ++lmem;
+ while(lreg<16 && reg->ub[lreg]) ++lreg;
+ }
+ return sse42_compare_string_explicit_len(emu, mem, lmem, reg, lreg, imm8);
+} \ No newline at end of file
diff --git a/src/emu/x64compstrings.h b/src/emu/x64compstrings.h
new file mode 100644
index 0000000..b2a785b
--- /dev/null
+++ b/src/emu/x64compstrings.h
@@ -0,0 +1,13 @@
+#ifndef __X64_CMPSTRINGS_H__
+#define __X64_CMPSTRINGS_H__
+
+#include <stdint.h>
+
+#include "regs.h"
+
+typedef struct x64emu_s x64emu_t;
+
+uint32_t sse42_compare_string_explicit_len(x64emu_t* emu, sse_regs_t* a, int la, sse_regs_t* b, int lb, uint8_t imm8);
+uint32_t sse42_compare_string_implicit_len(x64emu_t* emu, sse_regs_t* a, sse_regs_t* b, uint8_t imm8);
+
+#endif //__X64_CMPSTRINGS_H__ \ No newline at end of file
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 95077d4..8ac3e17 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -397,7 +397,7 @@ void ResetFlags(x64emu_t *emu)
const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits)
{
- static char buff[1000];
+ static char buff[4096];
static const char* regname[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI",
" R8", " R9", "R10", "R11", "R12", "R13", "R14", "R15"};
static const char* regname32[]={"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"};
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index 8076049..aa6584a 100644
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -44,6 +44,13 @@ typedef struct emu_flags_s {
uint32_t jmpbuf_ready:1; // the jmpbuf in the emu is ok and don't need refresh
} emu_flags_t;
+#ifdef ANDROID
+#include <setjmp.h>
+#define JUMPBUFF sigjmp_buf
+#else
+#define JUMPBUFF struct __jmp_buf_tag
+#endif
+
typedef struct x64emu_s {
// cpu
reg64_t regs[16];
@@ -54,10 +61,11 @@ typedef struct x64emu_s {
// fpu / mmx
mmx87_regs_t x87[8];
mmx87_regs_t mmx[8];
- x87control_t cw;
x87flags_t sw;
uint32_t top; // top is part of sw, but it's faster to have it separately
int fpu_stack;
+ x87control_t cw;
+ uint16_t dummy_cw; // align...
mmxcontrol_t mxcsr;
fpu_ld_t fpu_ld[8]; // for long double emulation / 80bits fld fst
fpu_ll_t fpu_ll[8]; // for 64bits fild / fist sequence
@@ -79,7 +87,8 @@ typedef struct x64emu_s {
uintptr_t prev2_ip;
#endif
// segments
- uint32_t segs[6]; // only 32bits value?
+ uint16_t segs[6]; // only 32bits value?
+ uint16_t dummy_seg6, dummy_seg7; // to stay aligned
uintptr_t segs_offs[6]; // computed offset associate with segment
uint32_t segs_serial[6]; // are seg offset clean (not 0) or does they need to be re-computed (0)? For GS, serial need to be the same as context->sel_serial
// parent context
@@ -104,7 +113,7 @@ typedef struct x64emu_s {
void* stack2free; // this is the stack to free (can be NULL)
void* init_stack; // initial stack (owned or not)
uint32_t size_stack; // stack size (owned or not)
- struct __jmp_buf_tag *jmpbuf;
+ JUMPBUFF* jmpbuf;
x64_ucontext_t *uc_link; // to handle setcontext
diff --git a/src/emu/x64int3.c b/src/emu/x64int3.c
index d58574c..227f06f 100644
--- a/src/emu/x64int3.c
+++ b/src/emu/x64int3.c
@@ -27,6 +27,7 @@
#include "box64context.h"
#include "librarian.h"
#include "elfload_dump.h"
+#include "signals.h"
#include <elf.h>
#include "elfloader.h"
@@ -40,7 +41,7 @@ x64emu_t* x64emu_fork(x64emu_t* emu, int forktype)
for (int i=my_context->atfork_sz-1; i>=0; --i)
if(my_context->atforks[i].prepare)
EmuCall(emu, my_context->atforks[i].prepare);
- int type = emu->type;
+ //int type = emu->type;
int v;
if(forktype==2) {
iFpppp_t forkpty = (iFpppp_t)emu->forkpty_info->f;
@@ -48,8 +49,8 @@ x64emu_t* x64emu_fork(x64emu_t* emu, int forktype)
emu->forkpty_info = NULL;
} else
v = fork();
- if(type == EMUTYPE_MAIN)
- thread_set_emu(emu);
+ /*if(type == EMUTYPE_MAIN)
+ thread_set_emu(emu);*/
if(v==EAGAIN || v==ENOMEM) {
// error...
} else if(v!=0) {
@@ -263,8 +264,9 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr)
} else if (!strcmp(s, "ov_read")) {
snprintf(buff, 256, "%04d|%p: Calling %s(%p, %p, %d, %d, %d, %d, %p)", tid, *(void**)(R_RSP), s, (void*)R_RDI, (void*)R_RSI, R_EDX, R_ECX, R_R8d, R_R9d, *(void**)(R_RSP+8));
} else if (!strcmp(s, "mmap64") || !strcmp(s, "mmap")) {
- snprintf(buff, 256, "%04d|%p: Calling %s(%p, %lu, 0x%x, 0x%x, %d, %ld)", tid, *(void**)(R_RSP), s,
+ snprintf(buff, 256, "%04d|%p: Calling %s(%p, 0x%lx, 0x%x, 0x%x, %d, %ld)", tid, *(void**)(R_RSP), s,
(void*)R_RDI, R_RSI, (int)(R_RDX), (int)R_RCX, (int)R_R8, R_R9);
+ perr = 3;
} else if (!strcmp(s, "sscanf")) {
tmp = (char*)(R_RSI);
snprintf(buff, 256, "%04d|%p: Calling %s(%p, \"%s\" (,%p))", tid, *(void**)(R_RSP), s, (void*)R_RDI, (tmp)?tmp:"(nil)", (void*)(R_RDX));
@@ -309,6 +311,9 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr)
snprintf(buff3, 64, " (errno=%d:\"%s\")", errno, strerror(errno));
else if(perr==2 && R_EAX==0)
snprintf(buff3, 64, " (errno=%d:\"%s\")", errno, strerror(errno));
+ else if(perr==3 && ((int64_t)R_RAX)==-1)
+ snprintf(buff3, 64, " (errno=%d:\"%s\")", errno, strerror(errno));
+
if(cycle_log)
snprintf(buffret, 128, "0x%lX%s%s", R_RAX, buff2, buff3);
else {
@@ -321,9 +326,9 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr)
}
return;
}
- if(0 && my_context->signals[SIGTRAP])
- raise(SIGTRAP);
- else
+ if(1 && my_context->signals[SIGTRAP])
+ emit_signal(emu, SIGTRAP, (void*)R_RIP, 128);
+ else
printf_log(LOG_INFO, "%04d|Warning, ignoring unsupported Int 3 call @%p\n", GetTID(), (void*)R_RIP);
//emu->quit = 1;
}
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index b027049..a914eb0 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -520,10 +520,8 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s)
CONDITIONAL_SET_FLAG(cf, F_CF);
/* OVERFLOW is set *IFF* cnt==1, then it is the
xor of CF and the most significant bit. Blecck. */
- /* parenthesized this expression since it appears to
- be causing OF to be misset */
- CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
- F_OF);
+ if(cnt == 1)
+ CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
}
return (uint8_t)res;
@@ -545,8 +543,8 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
res |= 1 << (cnt - 1);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
- F_OF);
+ if(cnt == 1)
+ CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
}
return (uint16_t)res;
}
@@ -567,8 +565,8 @@ uint32_t rcl32(x64emu_t *emu, uint32_t d, uint8_t s)
res |= 1 << (cnt - 1);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
- F_OF);
+ if(cnt == 1)
+ CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF);
}
return res;
}
@@ -589,8 +587,8 @@ uint64_t rcl64(x64emu_t *emu, uint64_t d, uint8_t s)
res |= 1LL << (cnt - 1);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 62) & 0x2)),
- F_OF);
+ if(cnt == 1)
+ CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF);
}
return res;
}
@@ -641,6 +639,11 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
(i.e. packed bit array or unpacked.)
*/
ocf = ACCESS_FLAG(F_CF) != 0;
+ /* OVERFLOW is set *IFF* cnt==1, then it is the
+ xor of CF and the most significant bit. Blecck. */
+ /* parenthesized... */
+ CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1,
+ F_OF);
} else
cf = (d >> (cnt - 1)) & 0x1;
@@ -669,13 +672,6 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
}
/* set the new carry flag, based on the variable "cf" */
CONDITIONAL_SET_FLAG(cf, F_CF);
- /* OVERFLOW is set *IFF* cnt==1, then it is the
- xor of CF and the most significant bit. Blecck. */
- /* parenthesized... */
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
- F_OF);
- }
}
return (uint8_t)res;
}
@@ -693,6 +689,8 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s)
if (cnt == 1) {
cf = d & 0x1;
ocf = ACCESS_FLAG(F_CF) != 0;
+ CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1,
+ F_OF);
} else
cf = (d >> (cnt - 1)) & 0x1;
mask = (1 << (16 - cnt)) - 1;
@@ -702,10 +700,6 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s)
res |= 1 << (16 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
- F_OF);
- }
}
return (uint16_t)res;
}
@@ -723,6 +717,8 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
if (cnt == 1) {
cf = d & 0x1;
ocf = ACCESS_FLAG(F_CF) != 0;
+ CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1,
+ F_OF);
} else
cf = (d >> (cnt - 1)) & 0x1;
mask = (1 << (32 - cnt)) - 1;
@@ -733,10 +729,6 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
res |= 1 << (32 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
- F_OF);
- }
}
return res;
}
@@ -754,6 +746,8 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
if (cnt == 1) {
cf = d & 0x1;
ocf = ACCESS_FLAG(F_CF) != 0;
+ CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1,
+ F_OF);
} else
cf = (d >> (cnt - 1)) & 0x1;
mask = (1LL << (64 - cnt)) - 1;
@@ -764,10 +758,6 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
res |= 1LL << (64 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 62) & 0x2)),
- F_OF);
- }
}
return res;
}
@@ -985,8 +975,7 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -1023,8 +1012,7 @@ uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -1049,8 +1037,7 @@ uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((res & 0x8000000000000000L) == 0x8000000000000000L) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -1081,7 +1068,7 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -1123,7 +1110,7 @@ uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
@@ -1149,7 +1136,7 @@ uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
res = d;
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(res >> 62), F_OF);
+ CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
} else {
CLEAR_FLAG(F_OF);
}
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h
index a0f465a..83f8b00 100644
--- a/src/emu/x64primop.h
+++ b/src/emu/x64primop.h
@@ -304,145 +304,193 @@ uint64_t sbb64 (x64emu_t *emu, uint64_t d, uint64_t s);
static inline uint8_t shl8(x64emu_t *emu, uint8_t d, uint8_t s)
{
- emu->df = d_shl8;
- emu->op1.u8 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u8 = s;
- emu->res.u8 = d << s;
+ emu->df = d_shl8;
+ emu->op1.u8 = d;
+ emu->op2.u8 = s;
+ emu->res.u8 = d << s;
- return emu->res.u8;
+ return emu->res.u8;
+ } else
+ return d;
}
static inline uint16_t shl16(x64emu_t *emu, uint16_t d, uint8_t s)
{
- emu->df = d_shl16;
- emu->op1.u16 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u16 = s;
- emu->res.u16 = d << s;
- return emu->res.u16;
+ emu->df = d_shl16;
+ emu->op1.u16 = d;
+ emu->op2.u16 = s;
+ emu->res.u16 = d << s;
+ return emu->res.u16;
+ } else
+ return d;
}
static inline uint32_t shl32(x64emu_t *emu, uint32_t d, uint8_t s)
{
- emu->df = d_shl32;
- emu->op1.u32 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u32 = s;
- emu->res.u32 = d << s;
+ emu->df = d_shl32;
+ emu->op1.u32 = d;
+ emu->op2.u32 = s;
+ emu->res.u32 = d << s;
- return emu->res.u32;
+ return emu->res.u32;
+ } else
+ return d;
}
static inline uint64_t shl64(x64emu_t *emu, uint64_t d, uint8_t s)
{
- emu->df = d_shl64;
- emu->op1.u64 = d;
+ if(s&0x3f) {
+ s &= 0x3f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x3f;
- emu->op2.u64 = s;
- emu->res.u64 = d << s;
+ emu->df = d_shl64;
+ emu->op1.u64 = d;
+ emu->op2.u64 = s;
+ emu->res.u64 = d << s;
- return emu->res.u64;
+ return emu->res.u64;
+ } else
+ return d;
}
static inline uint8_t shr8(x64emu_t *emu, uint8_t d, uint8_t s)
{
- emu->df = d_shr8;
- emu->op1.u8 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u8 = s;
- emu->res.u8 = d >> s;
+ emu->df = d_shr8;
+ emu->op1.u8 = d;
+ emu->op2.u8 = s;
+ emu->res.u8 = d >> s;
- return emu->res.u8;
+ return emu->res.u8;
+ } else
+ return d;
}
static inline uint16_t shr16(x64emu_t *emu, uint16_t d, uint8_t s)
{
- emu->df = d_shr16;
- emu->op1.u16 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u16 = s;
- emu->res.u16 = d >> s;
+ emu->df = d_shr16;
+ emu->op1.u16 = d;
+ emu->op2.u16 = s;
+ emu->res.u16 = d >> s;
- return emu->res.u16;
+ return emu->res.u16;
+ } else
+ return d;
}
static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s)
{
- emu->df = d_shr32;
- emu->op1.u32 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u32 = s;
- emu->res.u32 = d >> s;
+ emu->df = d_shr32;
+ emu->op1.u32 = d;
+ emu->op2.u32 = s;
+ emu->res.u32 = d >> s;
- return emu->res.u32;
+ return emu->res.u32;
+ } else
+ return d;
}
static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s)
{
- emu->df = d_shr64;
- emu->op1.u64 = d;
+ if(s&0x3f) {
+ s &= 0x3f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x3f;
- emu->op2.u64 = s;
- emu->res.u64 = d >> s;
+ emu->df = d_shr64;
+ emu->op1.u64 = d;
+ emu->op2.u64 = s;
+ emu->res.u64 = d >> s;
- return emu->res.u64;
+ return emu->res.u64;
+ } else
+ return d;
}
static inline uint8_t sar8(x64emu_t *emu, uint8_t d, uint8_t s)
{
- emu->df = d_sar8;
- emu->op1.u8 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u8 = s;
- emu->res.u8 = (uint8_t)(((int8_t)d)>>s);
+ emu->df = d_sar8;
+ emu->op1.u8 = d;
+ emu->op2.u8 = s;
+ emu->res.u8 = (uint8_t)(((int8_t)d)>>s);
- return emu->res.u8;
+ return emu->res.u8;
+ } else
+ return d;
}
static inline uint16_t sar16(x64emu_t *emu, uint16_t d, uint8_t s)
{
- emu->df = d_sar16;
- emu->op1.u16 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u16 = s;
- emu->res.u16 = (uint16_t)(((int16_t)d)>>s);
+ emu->df = d_sar16;
+ emu->op1.u16 = d;
+ emu->op2.u16 = s;
+ emu->res.u16 = (uint16_t)(((int16_t)d)>>s);
- return emu->res.u16;
+ return emu->res.u16;
+ } else
+ return d;
}
static inline uint32_t sar32(x64emu_t *emu, uint32_t d, uint8_t s)
{
- emu->df = d_sar32;
- emu->op1.u32 = d;
+ if(s&0x1f) {
+ s &= 0x1f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x1f;
- emu->op2.u32 = s;
- emu->res.u32 = (uint32_t)(((int32_t)d)>>s);
+ emu->df = d_sar32;
+ emu->op1.u32 = d;
+ emu->op2.u32 = s;
+ emu->res.u32 = (uint32_t)(((int32_t)d)>>s);
- return emu->res.u32;
+ return emu->res.u32;
+ } else
+ return d;
}
static inline uint64_t sar64(x64emu_t *emu, uint64_t d, uint8_t s)
{
- emu->df = d_sar64;
- emu->op1.u64 = d;
+ if(s&0x3f) {
+ s &= 0x3f;
+ if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs
- s &= 0x3f;
- emu->op2.u64 = s;
- emu->res.u64 = (uint64_t)(((int64_t)d)>>s);
+ emu->df = d_sar64;
+ emu->op1.u64 = d;
+ emu->op2.u64 = s;
+ emu->res.u64 = (uint64_t)(((int64_t)d)>>s);
- return emu->res.u64;
+ return emu->res.u64;
+ } else
+ return d;
}
static inline uint8_t sub8(x64emu_t *emu, uint8_t d, uint8_t s)
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 1f2f9dd..7faa06c 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -57,10 +57,8 @@ int Run(x64emu_t *emu, int step)
if(emu->quit)
return 0;
if(addr==0) {
- emu->quit = 1;
- printf_log(LOG_INFO, "%04d|Ask to run at NULL, quit silently\n", GetTID());
- print_cycle_log(LOG_INFO);
- return 0;
+ // Some programs, like VB6 VARA.exe, need to trigger that segfault to actually run... (ticket #830 in box86)
+ printf_log(LOG_INFO, "%04d|Ask to run at NULL, will segfault\n", GetTID());
}
//ref opcode: http://ref.x64asm.net/geek32.html#xA1
printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p is32bits=%d\n", emu, (void*)addr, (void*)R_RSP, is32bits);
@@ -83,12 +81,15 @@ x64emurun:
opcode = F8;
rep = 0;
- while((opcode==0xF2) || (opcode==0xF3)) {
- rep = opcode-0xF1;
+ while((opcode==0xF2) || (opcode==0xF3) || (opcode==0x3E) || (opcode==0x26)) {
+ switch (opcode) {
+ case 0xF2: rep = 1; break;
+ case 0xF3: rep = 2; break;
+ case 0x3E:
+ case 0x26: /* ignored*/ break;
+ }
opcode = F8;
}
- while((opcode==0x3E) || (opcode==0x26)) //Branch Taken Hint ignored
- opcode = F8;
rex.rex = 0;
rex.is32bits = is32bits;
if(!is32bits)
@@ -517,78 +518,13 @@ x64emurun:
GD->q[0] = imul32(emu, ED->dword[0], (uint32_t)tmp64s);
break;
case 0x6C: /* INSB DX */
- if(rex.is32bits) {
- tmp32u = rep?R_ECX:1;
- while(tmp32u--) {
- *(int8_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment
- if(ACCESS_FLAG(F_DF))
- R_EDI-=1;
- else
- R_EDI+=1;
- }
- if(rep)
- R_ECX = 0;
- } else {
- // this is a privilege opcode in 64bits, but not in 32bits...
- #ifndef TEST_INTERPRETOR
- emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
- STEP;
- #endif
- }
- break;
- case 0x6D: /* INSL DX */
- if(rex.is32bits) {
- tmp32u = rep?R_ECX:1;
- while(tmp32u--) {
- *(int32_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment
- if(ACCESS_FLAG(F_DF))
- R_EDI-=4;
- else
- R_EDI+=4;
- }
- if(rep)
- R_ECX = 0;
- } else {
- // this is a privilege opcode in 64bits, but not in 32bits...
- #ifndef TEST_INTERPRETOR
- emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
- STEP;
- #endif
- }
- break;
+ case 0x6D: /* INSD DX */
case 0x6E: /* OUTSB DX */
- if(rex.is32bits) {
- // faking port write, using explicit ES segment
- if(ACCESS_FLAG(F_DF))
- R_ESI-=rep?R_ECX:1;
- else
- R_ESI+=1?R_ECX:1;
- if(rep)
- R_ECX = 0;
- } else {
- // this is a privilege opcode in 64bits, but not in 32bits...
- #ifndef TEST_INTERPRETOR
- emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
- STEP;
- #endif
- }
- break;
- case 0x6F: /* OUTSL DX */
- if(rex.is32bits) {
- // faking port write, using explicit ES segment
- if(ACCESS_FLAG(F_DF))
- R_ESI-=(rep?R_ECX:1)*4;
- else
- R_ESI+=(rep?R_ECX:1)*4;
- if(rep)
- R_ECX = 0;
- } else {
- // this is a privilege opcode in 64bits, but not in 32bits...
- #ifndef TEST_INTERPRETOR
- emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
- STEP;
- #endif
- }
+ case 0x6F: /* OUTSD DX */
+ #ifndef TEST_INTERPRETOR
+ emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+ STEP;
+ #endif
break;
GOCOND(0x70
@@ -723,9 +659,21 @@ x64emurun:
}
} else {
if(rex.w) {
- GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]);
+ if((uintptr_t)ED&7) {
+ // not aligned, dont't try to "LOCK"
+ tmp64u = ED->q[0];
+ ED->q[0] = GD->q[0];
+ GD->q[0] = tmp64u;
+ } else
+ GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]);
} else {
- GD->q[0] = native_lock_xchg_d(ED, GD->dword[0]);
+ if((uintptr_t)ED&3) {
+ // not aligned, dont't try to "LOCK"
+ tmp32u = ED->dword[0];
+ ED->dword[0] = GD->dword[0];
+ GD->q[0] = tmp32u;
+ } else
+ GD->q[0] = native_lock_xchg_d(ED, GD->dword[0]);
}
}
#else
@@ -876,15 +824,6 @@ x64emurun:
case 0x9D: /* POPF */
emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
RESET_FLAGS(emu);
- #ifndef TEST_INTERPRETER
- if(ACCESS_FLAG(F_TF)) {
- R_RIP = addr;
- emit_signal(emu, SIGTRAP, (void*)addr, 1);
- if(emu->quit) goto fini;
- CLEAR_FLAG(F_TF);
- STEP;
- }
- #endif
break;
case 0x9E: /* SAHF */
CHECK_FLAGS(emu);
@@ -1355,7 +1294,7 @@ x64emurun:
STEP2
break;
case 0xC4: /* LES Gd,Ed */
- if(rex.is32bits) {
+ if(rex.is32bits && !(PK(0)&0x80)) {
nextop = F8;
GETED(0);
GETGD;
@@ -1368,7 +1307,7 @@ x64emurun:
}
break;
case 0xC5: /* LDS Gd,Ed */
- if(rex.is32bits) {
+ if(rex.is32bits && !(PK(0)&0x80)) {
nextop = F8;
GETED(0);
GETGD;
@@ -1536,6 +1475,22 @@ x64emurun:
}
break;
+ case 0xD4: /* AAM Ib */
+ if(rex.is32bits) {
+ R_AX = aam16(emu, R_AL, F8);
+ } else {
+ unimp = 1;
+ goto fini;
+ };
+ break;
+ case 0xD5: /* AAD Ib */
+ if(rex.is32bits) {
+ R_AX = aad16(emu, R_AX, F8);
+ } else {
+ unimp = 1;
+ goto fini;
+ };
+ break;
case 0xD6: /* SALC */
if(rex.is32bits) {
CHECK_FLAGS(emu);
@@ -1546,7 +1501,10 @@ x64emurun:
};
break;
case 0xD7: /* XLAT */
- R_AL = *(uint8_t*)(R_RBX + R_AL);
+ if(rex.w || rex.is32bits)
+ R_AL = *(uint8_t*)(R_RBX + R_AL);
+ else
+ R_AL = *(uint8_t*)((uintptr_t)R_EBX + R_AL);
break;
case 0xD8: /* x87 opcodes */
#ifdef TEST_INTERPRETER
@@ -1714,6 +1672,7 @@ x64emurun:
else
Push64(emu, addr);
addr += tmp32s;
+ addr = (uintptr_t)getAlternate((void*)addr);
STEP2
break;
case 0xE9: /* JMP Id */
@@ -1788,9 +1747,13 @@ x64emurun:
imul8(emu, EB->byte[0]);
break;
case 6: /* DIV Eb */
+ if(!EB->byte[0])
+ emit_div0(emu, (void*)R_RIP, 0);
div8(emu, EB->byte[0]);
break;
case 7: /* IDIV Eb */
+ if(!EB->byte[0])
+ emit_div0(emu, (void*)R_RIP, 0);
idiv8(emu, EB->byte[0]);
break;
}
@@ -1819,9 +1782,13 @@ x64emurun:
imul64_rax(emu, ED->q[0]);
break;
case 6: /* DIV Ed */
+ if(!ED->q[0])
+ emit_div0(emu, (void*)R_RIP, 0);
div64(emu, ED->q[0]);
break;
case 7: /* IDIV Ed */
+ if(!ED->q[0])
+ emit_div0(emu, (void*)R_RIP, 0);
idiv64(emu, ED->q[0]);
break;
}
@@ -1855,11 +1822,15 @@ x64emurun:
emu->regs[_DX].dword[1] = 0;
break;
case 6: /* DIV Ed */
+ if(!ED->dword[0])
+ emit_div0(emu, (void*)R_RIP, 0);
div32(emu, ED->dword[0]);
//emu->regs[_AX].dword[1] = 0; // already put high regs to 0
//emu->regs[_DX].dword[1] = 0;
break;
case 7: /* IDIV Ed */
+ if(!ED->dword[0])
+ emit_div0(emu, (void*)R_RIP, 0);
idiv32(emu, ED->dword[0]);
//emu->regs[_AX].dword[1] = 0;
//emu->regs[_DX].dword[1] = 0;
@@ -2011,11 +1982,27 @@ x64emurun:
unimp = 1;
goto fini;
}
+#ifndef TEST_INTERPRETER
+ // check the TRACE flag before going to next
+ if(ACCESS_FLAG(F_TF)) {
+ R_RIP = addr;
+ emit_signal(emu, SIGTRAP, (void*)addr, 1);
+ if(emu->quit) goto fini;
+ }
+#endif
R_RIP = addr;
}
fini:
+#ifndef TEST_INTERPRETER
+ // check the TRACE flag before going to out, in case it's a step by step scenario
+ if(!emu->quit && !emu->fork && !emu->uc_link && ACCESS_FLAG(F_TF)) {
+ R_RIP = addr;
+ emit_signal(emu, SIGTRAP, (void*)addr, 1);
+ if(emu->quit) goto fini;
+ }
+#endif
if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, CS is not default value: 0x%x\n", emu->segs[_CS]);
#ifndef TEST_INTERPRETER
printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit);
@@ -2026,16 +2013,16 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning,
// fork handling
if(emu->fork) {
addr = R_RIP;
- if(step)
- return 0;
int forktype = emu->fork;
emu->quit = 0;
emu->fork = 0;
emu = x64emu_fork(emu, forktype);
+ if(step)
+ return 0;
goto x64emurun;
}
// setcontext handling
- else if(emu->uc_link) {
+ else if(emu->quit && emu->uc_link) {
emu->quit = 0;
my_setcontext(emu, emu->uc_link);
addr = R_RIP;
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 466220b..3470c44 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
@@ -21,6 +22,7 @@
#include "my_cpuid.h"
#include "bridge.h"
#include "signals.h"
+#include "x64shaext.h"
#ifdef DYNAREC
#include "custommem.h"
#include "../dynarec/native_lock.h"
@@ -232,9 +234,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
tmp64s = INT32_MIN;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
tmp64s = nearbyintf(EX->f[i]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
tmp64s = floorf(EX->f[i]);
break;
@@ -335,6 +341,43 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
}
break;
+ case 0xC8: /* SHA1NEXTE Gx, Ex */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha1nexte(emu, GX, EX);
+ break;
+ case 0xC9: /* SHA1MSG1 Gx, Ex */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha1msg1(emu, GX, EX);
+ break;
+ case 0xCA: /* SHA1MSG2 Gx, Ex */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha1msg2(emu, GX, EX);
+ break;
+ case 0xCB: /* SHA256RNDS2 Gx, Ex (, XMM0) */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha256rnds2(emu, GX, EX);
+ break;
+ case 0xCC: /* SHA256MSG1 Gx, Ex */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha256msg1(emu, GX, EX);
+ break;
+ case 0xCD: /* SHA256MSG2 Gx, Ex */
+ nextop = F8;
+ GETGX;
+ GETEX(0);
+ sha256msg2(emu, GX, EX);
+ break;
+
case 0xF0: /* MOVBE Gd, Ed*/
nextop = F8;
GETGD;
@@ -384,6 +427,14 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
}
break;
+ case 0xCC: /* SHA1RNDS4 Gx, Ex, Ib */
+ nextop = F8;
+ GETGX;
+ GETEX(1);
+ tmp8u = F8;
+ sha1rnds4(emu, GX, EX, tmp8u);
+ break;
+
default:
return 0;
}
@@ -863,14 +914,24 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
}
break;
case 0xA4: /* SHLD Ed,Gd,Ib */
+ nextop = F8;
+ GETED(1);
+ GETGD;
+ tmp8u = F8;
+ if(rex.w)
+ ED->q[0] = shld64(emu, ED->q[0], GD->q[0], tmp8u);
+ else {
+ if(MODREG)
+ ED->q[0] = shld32(emu, ED->dword[0], GD->dword[0], tmp8u);
+ else
+ ED->dword[0] = shld32(emu, ED->dword[0], GD->dword[0], tmp8u);
+ }
+ break;
case 0xA5: /* SHLD Ed,Gd,CL */
nextop = F8;
- GETED((nextop==0xA4)?1:0);
+ GETED(0);
GETGD;
- if(opcode==0xA4)
- tmp8u = F8;
- else
- tmp8u = R_CL;
+ tmp8u = R_CL;
if(rex.w)
ED->q[0] = shld64(emu, ED->q[0], GD->q[0], tmp8u);
else {
@@ -1134,6 +1195,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
ED->dword[0] ^= (1<<tmp8u);
CLEAR_FLAG(F_CF);
}
+ if(MODREG)
+ ED->dword[1] = 0;
}
break;
case 6: /* BTR Ed, Ib */
@@ -1154,6 +1217,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
ED->dword[0] ^= (1<<tmp8u);
} else
CLEAR_FLAG(F_CF);
+ if(MODREG)
+ ED->dword[1] = 0;
}
break;
case 7: /* BTC Ed, Ib */
@@ -1174,6 +1239,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
else
CLEAR_FLAG(F_CF);
ED->dword[0] ^= (1<<tmp8u);
+ if(MODREG)
+ ED->dword[1] = 0;
}
break;
@@ -1734,7 +1801,16 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
tmp32u += (GM->ub[i]>EM->ub[i])?(GM->ub[i] - EM->ub[i]):(EM->ub[i] - GM->ub[i]);
GM->q = tmp32u;
break;
-
+ case 0xF7: /* MASKMOVQ Gm, Em */
+ nextop = F8;
+ GETEM(0);
+ GETGM;
+ for (int i = 0; i < 8; i++) {
+ if (EM->ub[i] & 0x80) {
+ ((reg64_t*)(emu->regs[_DI].q[0]))->byte[i] = GM->ub[i];
+ }
+ }
+ break;
case 0xF8: /* PSUBB Gm,Em */
nextop = F8;
GETEM(0);
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 587cc81..c39ff5e 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -272,6 +272,18 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
return 0;
}
break;
+ case 0xB7:
+ switch(rep) {
+ case 0: /* MOVZX Gd, FS:Ew */
+ nextop = F8;
+ GETEW_OFFS(0, tlsdata);
+ GETGD;
+ GD->q[0] = EW->word[0];
+ break;
+ default:
+ return 0;
+ }
+ break;
default:
return 0;
@@ -323,7 +335,20 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
GD->sdword[0] = ED->sdword[0]; // meh?
}
break;
-
+ case 0x64: /* FS: prefix */
+ #ifdef TEST_INTERPRETER
+ return Test64(test, rex, _FS, addr);
+ #else
+ return Run64(emu, rex, _FS, addr);
+ #endif
+ break;
+ case 0x65: /* GS: prefix */
+ #ifdef TEST_INTERPRETER
+ return Test64(test, rex, _GS, addr);
+ #else
+ return Run64(emu, rex, _GS, addr);
+ #endif
+ break;
case 0x66:
return Run6664(emu, rex, seg, addr);
case 0x67:
@@ -439,7 +464,12 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
else
GD->q[0] = tmp64u&0xffffffff;
break;
-
+ case 0x8E: /* MOV Seg, Seg:Ew */
+ nextop = F8;
+ GETED_OFFS(0, tlsdata);
+ emu->segs[((nextop&0x38)>>3)] = ED->word[0];
+ emu->segs_serial[((nextop&0x38)>>3)] = 0;
+ break;
case 0x8F: /* POP FS:Ed */
nextop = F8;
if(MODREG) {
@@ -460,6 +490,8 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
}
}
break;
+ case 0x90: /* NOP */
+ break;
case 0xA1: /* MOV EAX,FS:Od */
if(rex.is32bits) {
diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index 938fde4..3ba3af5 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -112,12 +112,55 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
GO(0x28, sub) /* SUB 0x29 ~> 0x2D */
GO(0x30, xor) /* XOR 0x31 ~> 0x35 */
+ case 0x06: /* PUSH ES */
+ if(!rex.is32bits) {
+ return 0;
+ }
+ Push32(emu, emu->segs[_ES]); // even if a segment is a 16bits, a 32bits push/pop is done
+ break;
+ case 0x07: /* POP ES */
+ if(!rex.is32bits) {
+ return 0;
+ }
+ emu->segs[_ES] = Pop32(emu); // no check, no use....
+ emu->segs_serial[_ES] = 0;
+ break;
+
case 0x0F: /* more opcdes */
- #ifdef TEST_INTERPRETER
- return Test660F(test, rex, addr);
- #else
- return Run660F(emu, rex, addr);
- #endif
+ switch(rep) {
+ case 0:
+ #ifdef TEST_INTERPRETER
+ return Test660F(test, rex, addr);
+ #else
+ return Run660F(emu, rex, addr);
+ #endif
+ case 1:
+ #ifdef TEST_INTERPRETER
+ return Test66F20F(test, rex, addr);
+ #else
+ return Run66F20F(emu, rex, addr);
+ #endif
+ case 2:
+ #ifdef TEST_INTERPRETER
+ return Test66F30F(test, rex, addr);
+ #else
+ return Run66F30F(emu, rex, addr);
+ #endif
+ }
+
+ case 0x1E: /* PUSH DS */
+ if(!rex.is32bits) {
+ return 0;
+ }
+ Push32(emu, emu->segs[_DS]); // even if a segment is a 16bits, a 32bits push/pop is done
+ break;
+ case 0x1F: /* POP DS */
+ if(!rex.is32bits) {
+ return 0;
+ }
+ emu->segs[_DS] = Pop32(emu); // no check, no use....
+ emu->segs_serial[_DS] = 0;
+ break;
case 0x39:
nextop = F8;
@@ -170,12 +213,13 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
case 0x51:
case 0x52:
case 0x53:
+ case 0x54:
case 0x55:
case 0x56:
case 0x57: /* PUSH Reg */
if(rex.is32bits) {
- tmp8u = opcode&7;
- Push16(emu, emu->regs[tmp8u].word[0]);
+ tmp16u = emu->regs[opcode&7].word[0];
+ Push16(emu, tmp16u);
} else
return 0;
break;
@@ -363,6 +407,12 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
else
GD->word[0] = (uint16_t)tmp64u;
break;
+ case 0x8E: /* MOV Seg,Ew */
+ nextop = F8;
+ GETEW(0);
+ emu->segs[((nextop&0x38)>>3)] = EW->word[0];
+ emu->segs_serial[((nextop&0x38)>>3)] = 0;
+ break;
case 0x90: /* NOP or XCHG R8d, AX*/
case 0x91:
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 902772e..81cbbf9 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
@@ -21,25 +22,26 @@
#include "bridge.h"
#include "modrm.h"
+#include "x64compstrings.h"
static uint8_t ff_mult(uint8_t a, uint8_t b)
{
int retval = 0;
for(int i = 0; i < 8; i++) {
- if((b & 1) == 1)
+ if((b & 1) == 1)
retval ^= a;
-
+
if((a & 0x80)) {
a <<= 1;
a ^= 0x1b;
} else {
a <<= 1;
}
-
+
b >>= 1;
}
-
+
return retval;
}
@@ -207,24 +209,28 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGM;
tmp64s = EX->d[0];
if (tmp64s==(int32_t)tmp64s && !isnan(EX->d[0]))
- GX->sd[0] = (int32_t)tmp64s;
+ GM->sd[0] = (int32_t)tmp64s;
else
- GX->sd[0] = INT32_MIN;
+ GM->sd[0] = INT32_MIN;
tmp64s = EX->d[1];
if (tmp64s==(int32_t)tmp64s && !isnan(EX->d[1]))
- GX->sd[1] = (int32_t)tmp64s;
+ GM->sd[1] = (int32_t)tmp64s;
else
- GX->sd[1] = INT32_MIN;
+ GM->sd[1] = INT32_MIN;
break;
case 0x2D: /* CVTPD2PI Gm, Ex */
nextop = F8;
GETEX(0);
GETGM;
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
i64[0] = nearbyint(EX->d[0]);
i64[1] = nearbyint(EX->d[1]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
i64[0] = floor(EX->d[0]);
i64[1] = floor(EX->d[1]);
@@ -514,7 +520,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
for(int i=1; i>=0; --i)
GX->sq[i] = EX->sd[i];
break;
-
+
case 0x28: /* PMULDQ Gx, Ex */
nextop = F8;
GETEX(0);
@@ -591,6 +597,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
for(int i=1; i>=0; --i)
GX->q[i] = EX->ud[i];
break;
+
case 0x37: /* PCMPGTQ Gx, Ex */
nextop = F8;
GETEX(0);
@@ -790,15 +797,15 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
break;
case 0xF0: /* MOVBE Gw, Ew */
nextop = F8;
- GETEX(0);
- GETGX;
- GX->uw[0] = __builtin_bswap16(EX->uw[0]);
+ GETED(0);
+ GETGD;
+ GD->word[0] = __builtin_bswap16(ED->word[0]);
break;
case 0xF1: /* MOVBE Ew, Gw */
nextop = F8;
- GETEX(0);
- GETGX;
- EX->uw[0] = __builtin_bswap16(GX->uw[0]);
+ GETED(0);
+ GETGD;
+ ED->word[0] = __builtin_bswap16(GD->word[0]);
break;
default:
return 0;
@@ -818,10 +825,14 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
else
tmp8u &= 3;
switch(tmp8u) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
for(int i=0; i<4; ++i)
GX->f[i] = nearbyintf(EX->f[i]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
for(int i=0; i<4; ++i)
GX->f[i] = floorf(EX->f[i]);
@@ -846,10 +857,14 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
else
tmp8u &= 3;
switch(tmp8u) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GX->d[0] = nearbyint(EX->d[0]);
GX->d[1] = nearbyint(EX->d[1]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GX->d[0] = floor(EX->d[0]);
GX->d[1] = floor(EX->d[1]);
@@ -874,9 +889,13 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
else
tmp8u &= 3;
switch(tmp8u) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GX->f[0] = nearbyintf(EX->f[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GX->f[0] = floorf(EX->f[0]);
break;
@@ -898,9 +917,13 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
else
tmp8u &= 3;
switch(tmp8u) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GX->d[0] = nearbyint(EX->d[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GX->d[0] = floor(EX->d[0]);
break;
@@ -923,7 +946,16 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GX->ud[i] = EX->ud[i];
}
break;
-
+ case 0x0D: /* PBLENDPD Gx, Ex, Ib */
+ nextop = F8;
+ GETEX(1);
+ GETGX;
+ tmp8u = F8;
+ for (int i=0; i<2; ++i) {
+ if(tmp8u&(1<<i))
+ GX->q[i] = EX->q[i];
+ }
+ break;
case 0x0E: /* PBLENDW Gx, Ex, Ib */
nextop = F8;
GETEX(1);
@@ -1047,7 +1079,6 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GX->d[0] = (tmp8u&(1<<(0)))?tmpd:0.0;
GX->d[1] = (tmp8u&(1<<(1)))?tmpd:0.0;
break;
-
case 0x42: /* MPSADBW Gx, Ex, Ib */
nextop = F8;
GETEX(1);
@@ -1088,6 +1119,65 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
}
break;
+ case 0x60: /* PCMPESTRM */
+ nextop = F8;
+ GETEX(1);
+ GETGX;
+ tmp8u = F8;
+ tmp32u = sse42_compare_string_explicit_len(emu, EX, R_EDX, GX, R_EAX, tmp8u);
+ if(tmp8u&0b1000000) {
+ switch(tmp8u&1) {
+ case 0: for(int i=0; i<16; ++i) GX->ub[i] = ((tmp32u>>i)&1)?0xff:0x00; break;
+ case 1: for(int i=0; i<8; ++i) GX->uw[i] = ((tmp32u>>i)&1)?0xffff:0x0000; break;
+ }
+ } else {
+ GX->q[1] = GX->q[0] = 0;
+ GX->uw[0] = tmp32u;
+ }
+ break;
+ case 0x61: /* PCMPESTRI */
+ nextop = F8;
+ GETEX(1);
+ GETGX;
+ tmp8u = F8;
+ tmp32u = sse42_compare_string_explicit_len(emu, EX, R_EDX, GX, R_EAX, tmp8u);
+ if(!tmp32u)
+ R_RCX = (tmp8u&1)?8:16;
+ else if(tmp8u&0b1000000)
+ R_RCX = 31-__builtin_clz(tmp32u);
+ else
+ R_RCX = __builtin_ffs(tmp32u) - 1;
+ break;
+ case 0x62: /* PCMPISTRM */
+ nextop = F8;
+ GETEX(1);
+ GETGX;
+ tmp8u = F8;
+ tmp32u = sse42_compare_string_implicit_len(emu, EX, GX, tmp8u);
+ if(tmp8u&0b1000000) {
+ switch(tmp8u&1) {
+ case 0: for(int i=0; i<16; ++i) GX->ub[i] = ((tmp32u>>i)&1)?0xff:0x00; break;
+ case 1: for(int i=0; i<8; ++i) GX->uw[i] = ((tmp32u>>i)&1)?0xffff:0x0000; break;
+ }
+ } else {
+ GX->q[1] = GX->q[0] = 0;
+ GX->uw[0] = tmp32u;
+ }
+ break;
+ case 0x63: /* PCMPISTRI */
+ nextop = F8;
+ GETEX(1);
+ GETGX;
+ tmp8u = F8;
+ tmp32u = sse42_compare_string_implicit_len(emu, EX, GX, tmp8u);
+ if(!tmp32u)
+ R_RCX = (tmp8u&1)?8:16;
+ else if(tmp8u&0b1000000)
+ R_RCX = 31-__builtin_clz(tmp32u);
+ else
+ R_RCX = __builtin_ffs(tmp32u) - 1;
+ break;
+
case 0xDF: // AESKEYGENASSIST Gx, Ex, u8
nextop = F8;
GETEX(1);
@@ -1113,7 +1203,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
return 0;
}
break;
-
+
GOCOND(0x40
, nextop = F8;
CHECK_FLAGS(emu);
@@ -1218,9 +1308,13 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
tmp64s = INT32_MIN;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
tmp64s = nearbyintf(EX->f[i]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
tmp64s = floorf(EX->f[i]);
break;
@@ -1285,7 +1379,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
if (isnan(GX->d[1]) || isnan(EX->d[1]) || isgreater(EX->d[1], GX->d[1]))
GX->d[1] = EX->d[1];
break;
-
+
case 0x60: /* PUNPCKLBW Gx,Ex */
nextop = F8;
GETEX(0);
@@ -1295,7 +1389,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
if(GX==EX)
for(int i=0; i<8; ++i)
GX->ub[2 * i + 1] = GX->ub[2 * i];
- else
+ else
for(int i=0; i<8; ++i)
GX->ub[2 * i + 1] = EX->ub[i];
break;
@@ -1538,7 +1632,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
} else {
EX->q[0] = EX->q[1] >> (tmp8u - 64);
EX->q[1] = 0;
- }
+ }
}
break;
case 6: /* PSLLQ Ex, Ib */
@@ -1827,7 +1921,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GW->word[0] = EW->word[0];
break;
- case 0xBA:
+ case 0xBA:
nextop = F8;
switch((nextop>>3)&7) {
case 4: /* BT Ew,Ib */
@@ -2096,7 +2190,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>15)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<8; ++i) GX->uw[i] >>= tmp8u;}
break;
case 0xD2: /* PSRLD Gx, Ex */
@@ -2105,7 +2199,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>31)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<4; ++i) GX->ud[i] >>= tmp8u;}
break;
case 0xD3: /* PSRLQ Gx, Ex */
@@ -2114,7 +2208,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>63)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<2; ++i) GX->q[i] >>= tmp8u;}
break;
case 0xD4: /* PADDQ Gx,Ex */
@@ -2229,7 +2323,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETEX(0);
GETGX;
tmp8u=(EX->q[0]>15)?15:EX->ub[0];
- for (int i=0; i<8; ++i)
+ for (int i=0; i<8; ++i)
GX->sw[i] >>= tmp8u;
break;
case 0xE2: /* PSRAD Gx, Ex */
@@ -2357,7 +2451,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>15)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<8; ++i) GX->uw[i] <<= tmp8u;}
break;
case 0xF2: /* PSLLD Gx, Ex */
@@ -2366,7 +2460,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>31)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<4; ++i) GX->ud[i] <<= tmp8u;}
break;
case 0xF3: /* PSLLQ Gx, Ex */
@@ -2375,7 +2469,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GETGX;
if(EX->q[0]>63)
{GX->q[0] = GX->q[1] = 0;}
- else
+ else
{tmp8u=EX->ub[0]; for (int i=0; i<2; ++i) GX->q[i] <<= tmp8u;}
break;
case 0xF4: /* PMULUDQ Gx,Ex */
@@ -2468,7 +2562,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GX->sd[2] += EX->sd[2];
GX->sd[3] += EX->sd[3];
break;
-
+
default:
return 0;
}
diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c
index 77c0249..9c29bd3 100644
--- a/src/emu/x64run66f0.c
+++ b/src/emu/x64run66f0.c
@@ -178,43 +178,43 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr)
case 0x81: /* GRP Ew,Iw */
case 0x83: /* GRP Ew,Ib */
nextop = F8;
- GETED((opcode==0x83)?1:2);
+ GETEW((opcode==0x83)?1:2);
tmp16s = (opcode==0x83)?(F8S):(F16S);
tmp16u = (uint16_t)tmp16s;
#if defined(DYNAREC) && !defined(TEST_INTERPRETER)
if(MODREG)
switch((nextop>>3)&7) {
- case 0: ED->word[0] = add16(emu, ED->word[0], tmp16u); break;
- case 1: ED->word[0] = or16(emu, ED->word[0], tmp16u); break;
- case 2: ED->word[0] = adc16(emu, ED->word[0], tmp16u); break;
- case 3: ED->word[0] = sbb16(emu, ED->word[0], tmp16u); break;
- case 4: ED->word[0] = and16(emu, ED->word[0], tmp16u); break;
- case 5: ED->word[0] = sub16(emu, ED->word[0], tmp16u); break;
- case 6: ED->word[0] = xor16(emu, ED->word[0], tmp16u); break;
- case 7: cmp16(emu, ED->word[0], tmp16u); break;
+ case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break;
+ case 1: EW->word[0] = or16(emu, EW->word[0], tmp16u); break;
+ case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break;
+ case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break;
+ case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break;
+ case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break;
+ case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break;
+ case 7: cmp16(emu, EW->word[0], tmp16u); break;
}
else
switch((nextop>>3)&7) {
- case 0: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = add16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 1: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = or16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 2: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = adc16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 3: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = sbb16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 4: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = and16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 5: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = sub16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 6: do { tmp16u2 = native_lock_read_h(ED); tmp16u2 = xor16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
- case 7: cmp16(emu, ED->word[0], tmp16u); break;
+ case 0: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = add16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 1: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = or16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 2: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = adc16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 3: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sbb16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 4: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = and16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 5: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = sub16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 6: do { tmp16u2 = native_lock_read_h(EW); tmp16u2 = xor16(emu, tmp16u2, tmp16u);} while(native_lock_write_h(ED, tmp16u2)); break;
+ case 7: cmp16(emu, EW->word[0], tmp16u); break;
}
#else
pthread_mutex_lock(&my_context->mutex_lock);
switch((nextop>>3)&7) {
- case 0: ED->word[0] = add16(emu, ED->word[0], tmp16u); break;
- case 1: ED->word[0] = or16(emu, ED->word[0], tmp16u); break;
- case 2: ED->word[0] = adc16(emu, ED->word[0], tmp16u); break;
- case 3: ED->word[0] = sbb16(emu, ED->word[0], tmp16u); break;
- case 4: ED->word[0] = and16(emu, ED->word[0], tmp16u); break;
- case 5: ED->word[0] = sub16(emu, ED->word[0], tmp16u); break;
- case 6: ED->word[0] = xor16(emu, ED->word[0], tmp16u); break;
- case 7: cmp16(emu, ED->word[0], tmp16u); break;
+ case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break;
+ case 1: EW->word[0] = or16(emu, EW->word[0], tmp16u); break;
+ case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break;
+ case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break;
+ case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break;
+ case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break;
+ case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break;
+ case 7: cmp16(emu, EW->word[0], tmp16u); break;
}
pthread_mutex_unlock(&my_context->mutex_lock);
#endif
@@ -222,35 +222,35 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr)
case 0xFF: /* GRP 5 Ed */
nextop = F8;
- GETED(0);
+ GETEW(0);
switch((nextop>>3)&7) {
case 0: /* INC Ed */
#if defined(DYNAREC) && !defined(TEST_INTERPRETER)
- if((uintptr_t)ED&1) {
+ if((uintptr_t)EW&1) {
//meh.
do {
- tmp16u = ED->word[0];
+ tmp16u = EW->word[0];
tmp16u &=~0xff;
- tmp16u |= native_lock_read_b(ED);
+ tmp16u |= native_lock_read_b(EW);
tmp16u = inc16(emu, tmp16u);
- } while(native_lock_write_b(ED, tmp16u&0xff));
- ED->word[0] = tmp16u;
+ } while(native_lock_write_b(EW, tmp16u&0xff));
+ EW->word[0] = tmp16u;
} else {
do {
- tmp16u = native_lock_read_h(ED);
- } while(native_lock_write_h(ED, inc16(emu, tmp16u)));
+ tmp16u = native_lock_read_h(EW);
+ } while(native_lock_write_h(EW, inc16(emu, tmp16u)));
}
#else
pthread_mutex_lock(&my_context->mutex_lock);
- ED->word[0] = inc16(emu, ED->word[0]);
+ EW->word[0] = inc16(emu, EW->word[0]);
pthread_mutex_unlock(&my_context->mutex_lock);
#endif
break;
case 1: /* DEC Ed */
#if defined(DYNAREC) && !defined(TEST_INTERPRETER)
do {
- tmp16u = native_lock_read_h(ED);
- } while(native_lock_write_h(ED, dec16(emu, tmp16u)));
+ tmp16u = native_lock_read_h(EW);
+ } while(native_lock_write_h(EW, dec16(emu, tmp16u)));
#else
pthread_mutex_lock(&my_context->mutex_lock);
ED->word[0] = dec16(emu, ED->word[0]);
diff --git a/src/emu/x64run66f20f.c b/src/emu/x64run66f20f.c
new file mode 100644
index 0000000..a4ad443
--- /dev/null
+++ b/src/emu/x64run66f20f.c
@@ -0,0 +1,88 @@
+#define _GNU_SOURCE
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <fenv.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "debug.h"
+#include "box64stack.h"
+#include "x64emu.h"
+#include "x64run.h"
+#include "x64emu_private.h"
+#include "x64run_private.h"
+#include "x64primop.h"
+#include "x64trace.h"
+#include "x87emu_private.h"
+#include "box64context.h"
+#include "bridge.h"
+
+#include "modrm.h"
+#include "x64compstrings.h"
+
+#ifdef TEST_INTERPRETER
+uintptr_t Test66F20F(x64test_t *test, rex_t rex, uintptr_t addr)
+#else
+uintptr_t Run66F20F(x64emu_t *emu, rex_t rex, uintptr_t addr)
+#endif
+{
+ uint8_t opcode;
+ uint8_t nextop;
+ uint8_t tmp8u;
+ int8_t tmp8s;
+ int16_t tmp16s;
+ uint16_t tmp16u;
+ int32_t tmp32s;
+ uint32_t tmp32u;
+ uint64_t tmp64u;
+ int64_t tmp64s, i64[4];
+ float tmpf;
+ double tmpd;
+ #ifndef NOALIGN
+ int is_nan;
+ #endif
+ reg64_t *oped, *opgd;
+ sse_regs_t *opex, *opgx, eax1, *opex2;
+ mmx87_regs_t *opem, *opgm;
+
+ #ifdef TEST_INTERPRETER
+ x64emu_t* emu = test->emu;
+ #endif
+ opcode = F8;
+
+ switch(opcode) {
+
+ case 0x38: // SSE 4.x
+ opcode = F8;
+ switch(opcode) {
+
+ case 0xF1: // CRC32 Gd, Ew
+ nextop = F8;
+ GETEW(0);
+ GETGD;
+ for(int j=0; j<2; ++j) {
+ GD->dword[0] ^= EW->byte[j];
+ for (int i = 0; i < 8; i++) {
+ if (GD->dword[0] & 1)
+ GD->dword[0] = (GD->dword[0] >> 1) ^ 0x82f63b78;
+ else
+ GD->dword[0] = (GD->dword[0] >> 1);
+ }
+ }
+ GD->dword[1] = 0;
+ break;
+
+ default:
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ return addr;
+}
diff --git a/src/emu/x64run66f30f.c b/src/emu/x64run66f30f.c
new file mode 100644
index 0000000..dd466ad
--- /dev/null
+++ b/src/emu/x64run66f30f.c
@@ -0,0 +1,64 @@
+#define _GNU_SOURCE
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <fenv.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "debug.h"
+#include "box64stack.h"
+#include "x64emu.h"
+#include "x64run.h"
+#include "x64emu_private.h"
+#include "x64run_private.h"
+#include "x64primop.h"
+#include "x64trace.h"
+#include "x87emu_private.h"
+#include "box64context.h"
+#include "bridge.h"
+
+#include "modrm.h"
+#include "x64compstrings.h"
+
+#ifdef TEST_INTERPRETER
+uintptr_t Test66F30F(x64test_t *test, rex_t rex, uintptr_t addr)
+#else
+uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
+#endif
+{
+ uint8_t opcode;
+ uint8_t nextop;
+ uint8_t tmp8u;
+ int8_t tmp8s;
+ int16_t tmp16s;
+ uint16_t tmp16u;
+ int32_t tmp32s;
+ uint32_t tmp32u;
+ uint64_t tmp64u;
+ int64_t tmp64s, i64[4];
+ float tmpf;
+ double tmpd;
+ #ifndef NOALIGN
+ int is_nan;
+ #endif
+ reg64_t *oped, *opgd;
+ sse_regs_t *opex, *opgx, eax1, *opex2;
+ mmx87_regs_t *opem, *opgm;
+
+ #ifdef TEST_INTERPRETER
+ x64emu_t* emu = test->emu;
+ #endif
+ opcode = F8;
+
+ switch(opcode) {
+
+
+ default:
+ return 0;
+ }
+ return addr;
+}
diff --git a/src/emu/x64run670f.c b/src/emu/x64run670f.c
index 015b371..0b3f149 100644
--- a/src/emu/x64run670f.c
+++ b/src/emu/x64run670f.c
@@ -25,6 +25,7 @@
#endif
#include "modrm.h"
+#include "x64compstrings.h"
#ifdef TEST_INTERPRETER
uintptr_t Test670F(x64test_t *test, rex_t rex, int rep, uintptr_t addr)
@@ -64,6 +65,14 @@ uintptr_t Run670F(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
}
break;
+ case 0x29: /* MOVAPS Ex,Gx */
+ nextop = F8;
+ GETEX32(0);
+ GETGX;
+ EX->q[0] = GX->q[0];
+ EX->q[1] = GX->q[1];
+ break;
+
case 0x2E:
// same for now
case 0x2F:
diff --git a/src/emu/x64run6764_32.c b/src/emu/x64run6764_32.c
index 6f6b060..92ed0b8 100644
--- a/src/emu/x64run6764_32.c
+++ b/src/emu/x64run6764_32.c
@@ -60,6 +60,30 @@ uintptr_t Run6764_32(x64emu_t *emu, rex_t rex, int rep, int seg, uintptr_t addr)
GW->word[0] = EW->word[0];
break;
+ case 0xA3: /* MOV FS:Od,EAX */
+ tmp32u = F16;
+ #ifdef TEST_INTERPRETER
+ test->memaddr = tlsdata + tmp32u;
+ test->memsize = 4;
+ *(uint32_t*)(test->mem) = R_EAX;
+ #else
+ *(uint32_t*)(tlsdata + tmp32u) = R_EAX;
+ #endif
+ break;
+
+ case 0xFF:
+ nextop = F8;
+ GETEW_OFFS_16(tlsdata);
+ switch((nextop>>3)&7) {
+ case 6: // Push Ed
+ tmp32u = ED->dword[0];
+ Push32(emu, tmp32u);
+ break;
+ default:
+ return 0;
+ }
+ break;
+
default:
return 0;
}
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index ffddd73..9d8beaa 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -28,6 +28,26 @@
#define PARITY(x) (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
+#ifdef ANDROID
+void EXPORT my___libc_init(x64emu_t* emu, void* raw_args __unused, void (*onexit)(void) __unused, int (*main)(int, char**, char**), void const * const structors __unused)
+{
+ //TODO: register fini
+ // let's cheat and set all args...
+ SetRDX(emu, (uintptr_t)my_context->envv);
+ SetRSI(emu, (uintptr_t)my_context->argv);
+ SetRDI(emu, (uintptr_t)my_context->argc);
+
+ printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main);
+ // should call structors->preinit_array and structors->init_array!
+ // call main and finish
+ PushExit(emu);
+ R_RIP=(uintptr_t)main;
+
+ DynaRun(emu);
+
+ emu->quit = 1; // finished!
+}
+#else
int32_t EXPORT my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
{
(void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end;
@@ -80,17 +100,16 @@ int32_t EXPORT my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, c
}
return (int)GetEAX(emu);
}
+#endif
const char* GetNativeName(void* p)
{
static char buff[500] = {0};
- #ifdef HAVE_TRACE
{
const char* n = getBridgeName(p);
if(n)
return n;
}
- #endif
Dl_info info;
if(dladdr(p, &info)==0) {
const char *ret = GetNameOffset(my_context->maplib, p);
@@ -105,7 +124,7 @@ const char* GetNativeName(void* p)
strcat(buff, " ("); strcat(buff, info.dli_fname); strcat(buff, ")");
}
} else {
- sprintf(buff, "%s(%s+%p)", "???", info.dli_fname, p);
+ sprintf(buff, "%s(%s+%p)", "???", info.dli_fname, (void*)(p-info.dli_fbase));
return buff;
}
}
@@ -278,7 +297,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_imul16:
lo = (uint16_t)emu->res.u32;
@@ -291,18 +316,30 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_imul32:
- if (((emu->res.u32 & 0x80000000) == 0 && emu->op1.u32 == 0x00) ||
- ((emu->res.u32 & 0x80000000) != 0 && emu->op1.u32 == 0xFFFFFFFF)) {
+ if ((((emu->res.u32 & 0x80000000) == 0) && emu->op1.u32 == 0x00) ||
+ (((emu->res.u32 & 0x80000000) != 0) && emu->op1.u32 == 0xFFFFFFFF)) {
CLEAR_FLAG(F_CF);
CLEAR_FLAG(F_OF);
} else {
SET_FLAG(F_CF);
- SET_FLAG(F_OF);
+ SET_FLAG(F_OF);
+ }
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
}
- CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
break;
case d_imul64:
if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) ||
@@ -313,7 +350,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_mul8:
lo = emu->res.u16 & 0xff;
@@ -325,7 +368,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_mul16:
lo = (uint16_t)emu->res.u32;
@@ -337,7 +386,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_mul32:
if (emu->op1.u32 == 0) {
@@ -347,7 +402,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_mul64:
if (emu->op1.u64 == 0) {
@@ -357,7 +418,13 @@ void UpdateFlags(x64emu_t *emu)
SET_FLAG(F_CF);
SET_FLAG(F_OF);
}
- CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ // to avoid noise in tests
+ CLEAR_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
+ CLEAR_FLAG(F_AF);
+ CLEAR_FLAG(F_PF);
+ }
break;
case d_or8:
CLEAR_FLAG(F_OF);
@@ -436,11 +503,14 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF);
- }
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
- } else {
- CLEAR_FLAG(F_OF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF);
@@ -448,6 +518,9 @@ void UpdateFlags(x64emu_t *emu)
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
SET_FLAG(F_ZF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shl16:
@@ -459,11 +532,14 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
- }
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
- } else {
- CLEAR_FLAG(F_OF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
CONDITIONAL_SET_FLAG((emu->op1.u16 << (emu->op2.u16-1)) & 0x8000, F_CF);
@@ -471,6 +547,9 @@ void UpdateFlags(x64emu_t *emu)
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
SET_FLAG(F_ZF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shl32:
@@ -482,12 +561,15 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
- }
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
- } else {
- CLEAR_FLAG(F_OF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^
+ (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
CONDITIONAL_SET_FLAG((emu->op1.u32 << (emu->op2.u32-1)) & 0x80000000, F_CF);
@@ -495,6 +577,9 @@ void UpdateFlags(x64emu_t *emu)
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
SET_FLAG(F_ZF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shl64:
@@ -504,12 +589,15 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
- }
- if (emu->op2.u64 == 1) {
- CONDITIONAL_SET_FLAG(((!!(emu->res.u64 & 0x8000000000000000LL)) ^
- (ACCESS_FLAG(F_CF) != 0)), F_OF);
- } else {
- CLEAR_FLAG(F_OF);
+ if (emu->op2.u64 == 1) {
+ CONDITIONAL_SET_FLAG(((!!(emu->res.u64 & 0x8000000000000000LL)) ^
+ (ACCESS_FLAG(F_CF) != 0)), F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_sar8:
@@ -520,19 +608,27 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF);
CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
+ if(emu->op2.u8==1)
+ CLEAR_FLAG(F_OF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
if (emu->op1.u8&0x80) {
SET_FLAG(F_CF);
- CLEAR_FLAG(F_ZF);
SET_FLAG(F_SF);
+ CLEAR_FLAG(F_ZF);
SET_FLAG(F_PF);
} else {
CLEAR_FLAG(F_CF);
- SET_FLAG(F_ZF);
CLEAR_FLAG(F_SF);
+ SET_FLAG(F_ZF);
SET_FLAG(F_PF);
}
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_sar16:
@@ -543,6 +639,11 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
+ if(emu->op2.u16==1)
+ CLEAR_FLAG(F_OF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
if (emu->op1.u16&0x8000) {
@@ -556,6 +657,9 @@ void UpdateFlags(x64emu_t *emu)
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
}
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_sar32:
@@ -566,6 +670,11 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+ if(emu->op2.u32==1)
+ CLEAR_FLAG(F_OF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
} else {
if (emu->op1.u32&0x80000000) {
@@ -579,6 +688,9 @@ void UpdateFlags(x64emu_t *emu)
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
}
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_sar64:
@@ -588,6 +700,11 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if(emu->op2.u64==1)
+ CLEAR_FLAG(F_OF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shr8:
@@ -599,15 +716,21 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF);
+ CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF);
}
} else {
CONDITIONAL_SET_FLAG((emu->op1.u8 >> (emu->op2.u8-1)) & 0x1, F_CF);
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
SET_FLAG(F_ZF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shr16:
@@ -619,15 +742,21 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF);
+ CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF);
}
} else {
CLEAR_FLAG(F_CF);
SET_FLAG(F_ZF);
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shr32:
@@ -639,15 +768,21 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF);
+ CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF);
}
} else {
CLEAR_FLAG(F_CF);
SET_FLAG(F_ZF);
CLEAR_FLAG(F_SF);
SET_FLAG(F_PF);
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
break;
case d_shr64:
@@ -658,9 +793,96 @@ void UpdateFlags(x64emu_t *emu)
CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF);
+ }
+ if(box64_dynarec_test) {
+ CLEAR_FLAG(F_AF);
+ }
}
- if (cnt == 1) {
- CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF);
+ break;
+ case d_shrd16:
+ cnt = emu->op2.u16;
+ if (cnt > 0) {
+ cc = emu->op1.u16 & (1 << (cnt - 1));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF);
+ }
+ }
+ break;
+ case d_shrd32:
+ cnt = emu->op2.u32;
+ if (cnt > 0) {
+ cc = emu->op1.u32 & (1 << (cnt - 1));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+ }
+ }
+ break;
+ case d_shrd64:
+ cnt = emu->op2.u64;
+ if (cnt > 0) {
+ cc = emu->op1.u64 & (1LL << (cnt - 1));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+ }
+ }
+ break;
+ case d_shld16:
+ cnt = emu->op2.u16;
+ if (cnt > 0) {
+ cc = emu->op1.u16 & (1 << (16 - cnt));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ }
+ break;
+ case d_shld32:
+ cnt = emu->op2.u32;
+ if (cnt > 0) {
+ cc = emu->op1.u32 & (1 << (32 - cnt));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
+ }
+ break;
+ case d_shld64:
+ cnt = emu->op2.u64;
+ if (cnt > 0) {
+ cc = emu->op1.u64 & (1LL << (64 - cnt));
+ CONDITIONAL_SET_FLAG(cc, F_CF);
+ CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
+ CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF);
+ CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+ if (cnt == 1) {
+ CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+ } else {
+ CLEAR_FLAG(F_OF);
+ }
}
break;
case d_sub8:
@@ -1032,7 +1254,8 @@ int printFunctionAddr(uintptr_t nextaddr, const char* text)
#ifdef HAVE_TRACE
extern uint64_t start_cnt;
-#define PK(a) (*(uint8_t*)(ip+a))
+#define PK(a) (*(uint8_t*)(ip+a))
+#define PKS(a) (*(int8_t*)(ip+a))
#define PK32(a) (*(int32_t*)((uint8_t*)(ip+a)))
#define PK64(a) (*(int64_t*)((uint8_t*)(ip+a)))
@@ -1092,7 +1315,8 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec)
printf_log(LOG_NONE, " => STACK_TOP: %p", *(void**)(R_RSP));
printFunctionAddr(ip, "here: ");
} else if((peek==0x55 || peek==0x53) && !is32bits) {
- printFunctionAddr(*(uintptr_t*)(R_RSP), " STACK_TOP: ");
+ if(!printFunctionAddr(*(uintptr_t*)(R_RSP), " STACK_TOP: "))
+ printf_log(LOG_NONE, " STACK_TOP: %p ", (void*)*(uintptr_t*)(R_RSP));
} else if((peek==0x55 || peek==0x56) && is32bits) {
if(!printFunctionAddr(*(uint32_t*)(R_RSP), " STACK_TOP: "))
printf_log(LOG_NONE, " STACK_TOP: %p ", (void*)(uintptr_t)*(uint32_t*)(R_RSP));
@@ -1103,18 +1327,25 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec)
printFunctionAddr(nextaddr, "=> ");
} else if(peek==0xFF) {
if(PK(1)==0x25) {
- uintptr_t nextaddr = *(uintptr_t*)(ip + 6 + PK32(2));
+ uintptr_t nextaddr = is32bits?(*(uint32_t*)(uintptr_t)PK32(2)):(*(uintptr_t*)(ip + 6 + PK32(2)));
+ if(!printFunctionAddr(nextaddr, "=> "))
+ printf_log(LOG_NONE, " => %p", (void*)nextaddr);
+ } else if(PK(1)==0x15) {
+ uintptr_t nextaddr = is32bits?(*(uint32_t*)(uintptr_t)PK32(2)):(*(uintptr_t*)(ip + 6 + PK32(2)));
+ if(!printFunctionAddr(nextaddr, "=> "))
+ printf_log(LOG_NONE, " => %p", (void*)nextaddr);
+ } else if(PK(1)==0x60) {
+ uintptr_t nextaddr = *(uintptr_t*)(R_RAX+PK(2));
if(!printFunctionAddr(nextaddr, "=> "))
printf_log(LOG_NONE, " => %p", (void*)nextaddr);
} else if((PK(1)==0x14) && (PK(2)==0x25)) {
- uintptr_t nextaddr = *(uintptr_t*)(uintptr_t)PK32(3);
+ uintptr_t nextaddr = is32bits?(*(uint32_t*)(uintptr_t)PK32(3)):(*(uintptr_t*)(uintptr_t)PK32(3));
printf_log(LOG_NONE, " => %p", (void*)nextaddr);
printFunctionAddr(nextaddr, "=> ");
} else if((PK(1)==0x14) && (PK(2)==0xC2) && rex.rex==0x41) {
uintptr_t nextaddr = *(uintptr_t*)(R_R10 + R_RAX*8);
printf_log(LOG_NONE, " => %p", (void*)nextaddr);
printFunctionAddr(nextaddr, "=> ");
-
}
}
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index dcda399..f90a35e 100644
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -129,6 +129,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step);
uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr);
uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr);
uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run66F20F(x64emu_t *emu, rex_t rex, uintptr_t addr);
+uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr);
uintptr_t Run6664(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr);
uintptr_t Run66D9(x64emu_t *emu, rex_t rex, uintptr_t addr);
uintptr_t Run66DD(x64emu_t *emu, rex_t rex, uintptr_t addr);
@@ -155,6 +157,8 @@ uintptr_t Test0F(x64test_t *test, rex_t rex, uintptr_t addr, int *step);
uintptr_t Test64(x64test_t *test, rex_t rex, int seg, uintptr_t addr);
uintptr_t Test66(x64test_t *test, rex_t rex, int rep, uintptr_t addr);
uintptr_t Test660F(x64test_t *test, rex_t rex, uintptr_t addr);
+uintptr_t Test66F20F(x64test_t *test, rex_t rex, uintptr_t addr);
+uintptr_t Test66F30F(x64test_t *test, rex_t rex, uintptr_t addr);
uintptr_t Test6664(x64test_t *test, rex_t rex, int seg, uintptr_t addr);
uintptr_t Test66D9(x64test_t *test, rex_t rex, uintptr_t addr);
uintptr_t Test66DD(x64test_t *test, rex_t rex, uintptr_t addr);
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index e1dbace..a7ff67b 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -48,6 +48,8 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
#endif
opcode = F8;
+ while(opcode==0x2E) // ignoring CS: prefix
+ opcode = F8;
// REX prefix before the F0 are ignored
rex.rex = 0;
if(!rex.is32bits)
@@ -328,16 +330,31 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
}
} while(tmp32s);
else {
- do {
- tmp32u = native_lock_read_d(ED);
- cmp32(emu, R_EAX, tmp32u);
- if(ACCESS_FLAG(F_ZF)) {
- tmp32s = native_lock_write_d(ED, GD->dword[0]);
- } else {
- R_EAX = tmp32u;
- tmp32s = 0;
- }
- } while(tmp32s);
+ if(((uintptr_t)ED)&3) {
+ do {
+ tmp32u = ED->q[0] & ~0xffLL;
+ tmp32u |= native_lock_read_b(ED);
+ cmp64(emu, R_RAX, tmp32u);
+ if(ACCESS_FLAG(F_ZF)) {
+ tmp32s = native_lock_write_b(ED, GD->dword[0]&0xff);
+ if(!tmp32s)
+ ED->dword[0] = GD->dword[0];
+ } else {
+ R_EAX = tmp32u;
+ tmp32s = 0;
+ }
+ } while(tmp32s);
+ } else
+ do {
+ tmp32u = native_lock_read_d(ED);
+ cmp32(emu, R_EAX, tmp32u);
+ if(ACCESS_FLAG(F_ZF)) {
+ tmp32s = native_lock_write_d(ED, GD->dword[0]);
+ } else {
+ R_EAX = tmp32u;
+ tmp32s = 0;
+ }
+ } while(tmp32s);
emu->regs[_AX].dword[1] = 0;
if(MODREG)
ED->dword[1] = 0;
@@ -667,16 +684,18 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
#else
pthread_mutex_lock(&my_context->mutex_lock);
if(rex.w) {
- tmp64u = add64(emu, ED->q[0], GD->q[0]);
- GD->q[0] = ED->q[0];
- ED->q[0] = tmp64u;
+ tmp64u = ED->q[0];
+ tmp64u2 = add64(emu, tmp64u, GD->q[0]);
+ GD->q[0] = tmp64u;
+ ED->q[0] = tmp64u2;
} else {
- tmp32u = add32(emu, ED->dword[0], GD->dword[0]);
- GD->q[0] = ED->dword[0];
+ tmp32u = ED->dword[0];
+ tmp32u2 = add32(emu, tmp32u, GD->dword[0]);
+ GD->q[0] = tmp32u;
if(MODREG)
- ED->q[0] = tmp32u;
+ ED->q[0] = tmp32u2;
else
- ED->dword[0] = tmp32u;
+ ED->dword[0] = tmp32u2;
}
pthread_mutex_unlock(&my_context->mutex_lock);
#endif
@@ -929,7 +948,18 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
}
} else {
if(rex.w) {
- GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]);
+ if((uintptr_t)ED&7) {
+ // unaligned
+ do {
+ tmp64u = ED->q[0] & 0xffffffffffffff00LL;
+ tmp64u |= native_lock_read_b(ED);
+
+ } while(native_lock_write_b(ED, GD->byte[0]));
+ ED->q[0] = GD->q[0];
+ GD->q[0] = tmp64u;
+ } else {
+ GD->q[0] = native_lock_xchg_dd(ED, GD->q[0]);
+ }
} else {
GD->dword[0] = native_lock_xchg_d(ED, GD->dword[0]);
}
diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
index 3375031..020a896 100644
--- a/src/emu/x64runf20f.c
+++ b/src/emu/x64runf20f.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
@@ -113,9 +114,13 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
GD->q[0] = 0x8000000000000000LL;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GD->sq[0] = nearbyint(EX->d[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GD->sq[0] = floor(EX->d[0]);
break;
@@ -131,9 +136,13 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
GD->dword[0] = 0x80000000;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GD->sdword[0] = nearbyint(EX->d[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GD->sdword[0] = floor(EX->d[0]);
break;
@@ -147,6 +156,44 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
GD->dword[1] = 0;
}
break;
+
+ case 0x38: // more opcodes
+ opcode = F8;
+ switch(opcode) {
+
+ case 0xF0: // CRC32 Gd, Eb
+ nextop = F8;
+ GETEB(0);
+ GETGD;
+ GD->dword[0] ^= EB->byte[0];
+ for (int i = 0; i < 8; i++) {
+ if (GD->dword[0] & 1)
+ GD->dword[0] = (GD->dword[0] >> 1) ^ 0x82f63b78;
+ else
+ GD->dword[0] = (GD->dword[0] >> 1);
+ }
+ GD->dword[1] = 0;
+ break;
+ case 0xF1: // CRC32 Gd, Ed
+ nextop = F8;
+ GETED(0);
+ GETGD;
+ for(int j=0; j<4*(rex.w+1); ++j) {
+ GD->dword[0] ^= ED->byte[j];
+ for (int i = 0; i < 8; i++) {
+ if (GD->dword[0] & 1)
+ GD->dword[0] = (GD->dword[0] >> 1) ^ 0x82f63b78;
+ else
+ GD->dword[0] = (GD->dword[0] >> 1);
+ }
+ }
+ GD->dword[1] = 0;
+ break;
+
+ default:
+ return 0;
+ }
+ break;
case 0x51: /* SQRTSD Gx, Ex */
nextop = F8;
@@ -325,10 +372,14 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
GETEX(0);
GETGX;
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
tmp64s0 = nearbyint(EX->d[0]);
tmp64s1 = nearbyint(EX->d[1]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
tmp64s0 = floor(EX->d[0]);
tmp64s1 = floor(EX->d[1]);
diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c
index d5b70b2..9f56441 100644
--- a/src/emu/x64runf30f.c
+++ b/src/emu/x64runf30f.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
@@ -42,6 +43,11 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
x64emu_t*emu = test->emu;
#endif
+ #ifdef TERMUX
+ extern int isinff(float);
+ extern int isnanf(float);
+ #endif
+
opcode = F8;
switch(opcode) {
@@ -119,9 +125,13 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
GD->q[0] = 0x8000000000000000LL;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
GD->sq[0] = nearbyintf(EX->f[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
GD->sq[0] = floorf(EX->f[0]);
break;
@@ -137,9 +147,13 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
tmp64s = INT32_MIN;
else
switch(emu->mxcsr.f.MXCSR_RC) {
- case ROUND_Nearest:
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
tmp64s = nearbyintf(EX->f[0]);
+ fesetround(round);
break;
+ }
case ROUND_Down:
tmp64s = floorf(EX->f[0]);
break;
diff --git a/src/emu/x64shaext.c b/src/emu/x64shaext.c
new file mode 100644
index 0000000..a0533bb
--- /dev/null
+++ b/src/emu/x64shaext.c
@@ -0,0 +1,194 @@
+#include <stdint.h>
+
+#include "box64stack.h"
+#include "x64emu.h"
+#include "x64run_private.h"
+#include "x64emu_private.h"
+#include "x64shaext.h"
+
+static uint32_t rol(uint32_t a, int n)
+{
+ n = n&31;
+ if(!n)
+ return a;
+ return (a<<n) | (a>>(32-n));
+}
+
+static uint32_t ror(uint32_t a, int n)
+{
+ n = n&31;
+ if(!n)
+ return a;
+ return (a>>n) | (a<<(32-n));
+}
+
+static uint32_t f0(uint32_t B, uint32_t C, uint32_t D)
+{
+ return (B & C) ^ ((~B) & D);
+}
+
+static uint32_t f1(uint32_t B, uint32_t C, uint32_t D)
+{
+ return B ^ C ^ D;
+}
+
+static uint32_t f2(uint32_t B, uint32_t C, uint32_t D)
+{
+ return (B & C) ^ (B & D) ^ (C & D);
+}
+
+static uint32_t f3(uint32_t B, uint32_t C, uint32_t D)
+{
+ return B ^ C ^ D;
+}
+
+static uint32_t Ch(uint32_t E, uint32_t F, uint32_t G)
+{
+ return (E & F) ^ ((~E) & G);
+}
+
+static uint32_t Maj(uint32_t A, uint32_t B, uint32_t C)
+{
+ return (A & B) ^ (A & C) ^ (B & C);
+}
+
+static uint32_t sigma0(uint32_t A)
+{
+ return ror(A, 2) ^ ror(A, 13) ^ ror(A, 22);
+}
+static uint32_t sigma1(uint32_t E)
+{
+ return ror(E, 6) ^ ror(E, 11) ^ ror(E, 25);
+}
+static uint32_t tho0(uint32_t W)
+{
+ return ror(W, 7) ^ ror(W, 18) ^ (W>>3);
+}
+static uint32_t tho1(uint32_t W)
+{
+ return ror(W, 17) ^ ror(W, 19) ^ (W>>10);
+}
+
+static const uint32_t Ks[] = { 0x5A827999, 0x6ED9EBA1, 0X8F1BBCDC, 0xCA62C1D6 };
+
+void sha1nexte(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t tmp = rol(xmm1->ud[3], 30);
+ xmm1->ud[3] = xmm2->ud[3] + tmp;
+ xmm1->ud[2] = xmm2->ud[2];
+ xmm1->ud[1] = xmm2->ud[1];
+ xmm1->ud[0] = xmm2->ud[0];
+}
+
+void sha1msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t w0 = xmm1->ud[3];
+ uint32_t w1 = xmm1->ud[2];
+ uint32_t w2 = xmm1->ud[1];
+ uint32_t w3 = xmm1->ud[0];
+ uint32_t w4 = xmm2->ud[3];
+ uint32_t w5 = xmm2->ud[2];
+ xmm1->ud[3] = w2 ^ w0;
+ xmm1->ud[2] = w3 ^ w1;
+ xmm1->ud[1] = w4 ^ w2;
+ xmm1->ud[0] = w5 ^ w3;
+}
+
+void sha1msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t w13 = xmm2->ud[2];
+ uint32_t w14 = xmm2->ud[1];
+ uint32_t w15 = xmm2->ud[0];
+ uint32_t w16 = rol(xmm1->ud[3] ^ w13, 1);
+ uint32_t w17 = rol(xmm1->ud[2] ^ w14, 1);
+ uint32_t w18 = rol(xmm1->ud[1] ^ w15, 1);
+ uint32_t w19 = rol(xmm1->ud[0] ^ w16, 1);
+ xmm1->ud[3] = w16;
+ xmm1->ud[2] = w17;
+ xmm1->ud[1] = w18;
+ xmm1->ud[0] = w19;
+}
+
+void sha256msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t w4 = xmm2->ud[0];
+ uint32_t w3 = xmm1->ud[3];
+ uint32_t w2 = xmm1->ud[2];
+ uint32_t w1 = xmm1->ud[1];
+ uint32_t w0 = xmm1->ud[0];
+ xmm1->ud[3] = w3 + tho0(w4);
+ xmm1->ud[2] = w2 + tho0(w3);
+ xmm1->ud[1] = w1 + tho0(w2);
+ xmm1->ud[0] = w0 + tho0(w1);
+}
+
+void sha256msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t w14 = xmm2->ud[2];
+ uint32_t w15 = xmm2->ud[3];
+ uint32_t w16 = xmm1->ud[0] + tho1(w14);
+ uint32_t w17 = xmm1->ud[1] + tho1(w15);
+ uint32_t w18 = xmm1->ud[2] + tho1(w16);
+ uint32_t w19 = xmm1->ud[3] + tho1(w17);
+ xmm1->ud[3] = w19;
+ xmm1->ud[2] = w18;
+ xmm1->ud[1] = w17;
+ xmm1->ud[0] = w16;
+}
+
+void sha1rnds4(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2, uint8_t ib)
+{
+ uint32_t K = Ks[ib&3];
+ uint32_t(*f)(uint32_t , uint32_t , uint32_t) = NULL;
+ switch (ib&3) {
+ case 0: f = f0; break;
+ case 1: f = f1; break;
+ case 2: f = f2; break;
+ case 3: f = f3; break;
+ }
+ uint32_t A = xmm1->ud[3];
+ uint32_t B = xmm1->ud[2];
+ uint32_t C = xmm1->ud[1];
+ uint32_t D = xmm1->ud[0];
+ uint32_t E = 0;
+ for(int i=0; i<4; ++i) {
+ uint32_t new_A = f(B, C, D) + rol(A, 5) + xmm2->ud[3-i] + E + K;
+ E = D;
+ D = C;
+ C = rol(B, 30);
+ B = A;
+ A = new_A;
+ }
+ xmm1->ud[3] = A;
+ xmm1->ud[2] = B;
+ xmm1->ud[1] = C;
+ xmm1->ud[0] = D;
+}
+
+void sha256rnds2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2)
+{
+ uint32_t A = xmm2->ud[3];
+ uint32_t B = xmm2->ud[2];
+ uint32_t C = xmm1->ud[3];
+ uint32_t D = xmm1->ud[2];
+ uint32_t E = xmm2->ud[1];
+ uint32_t F = xmm2->ud[0];
+ uint32_t G = xmm1->ud[1];
+ uint32_t H = xmm1->ud[0];
+ for(int i=0; i<2; ++i) {
+ uint32_t new_A = Ch(E, F, G) + sigma1(E) + emu->xmm[0].ud[i] + H + Maj(A, B, C) + sigma0(A);
+ uint32_t new_E = Ch(E, F, G) + sigma1(E) + emu->xmm[0].ud[i] + H + D;
+ H = G;
+ G = F;
+ F = E;
+ E = new_E;
+ D = C;
+ C = B;
+ B = A;
+ A = new_A;
+ }
+ xmm1->ud[3] = A;
+ xmm1->ud[2] = B;
+ xmm1->ud[1] = E;
+ xmm1->ud[0] = F;
+} \ No newline at end of file
diff --git a/src/emu/x64shaext.h b/src/emu/x64shaext.h
new file mode 100644
index 0000000..a86102d
--- /dev/null
+++ b/src/emu/x64shaext.h
@@ -0,0 +1,18 @@
+#ifndef __X64_SHAEXT_H__
+#define __X64_SHAEXT_H__
+
+#include <stdint.h>
+
+#include "regs.h"
+
+typedef struct x64emu_s x64emu_t;
+
+void sha1nexte(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+void sha1msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+void sha1msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+void sha256msg1(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+void sha256msg2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+void sha1rnds4(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2, uint8_t ib);
+void sha256rnds2(x64emu_t* emu, sse_regs_t* xmm1, sse_regs_t* xmm2);
+
+#endif //__X64_SHAEXT_H__ \ No newline at end of file
diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c
index 24dd442..c450ef0 100644
--- a/src/emu/x64syscall.c
+++ b/src/emu/x64syscall.c
@@ -5,6 +5,8 @@
#include <string.h>
#include <sys/syscall.h> /* For SYS_xxx definitions */
+#include <sys/signalfd.h>
+#include <sys/eventfd.h>
#include <unistd.h>
#include <time.h>
#include <sys/mman.h>
@@ -73,12 +75,11 @@ int fcntl(int fd, int cmd, ... /* arg */ );
// Syscall table for x86_64 can be found
typedef struct scwrap_s {
- uint32_t x64s; // 32 bits?
int nats;
int nbpars;
} scwrap_t;
-static scwrap_t syscallwrap[] = {
+static const scwrap_t syscallwrap[] = {
//{ 0, __NR_read, 3 }, // wrapped so SA_RESTART can be handled by libc
//{ 1, __NR_write, 3 }, // same
//{ 2, __NR_open, 3 }, // flags need transformation
@@ -87,194 +88,194 @@ static scwrap_t syscallwrap[] = {
//{ 5, __NR_fstat, 2},
//{ 6, __NR_lstat, 2},
#ifdef __NR_poll
- { 7, __NR_poll, 3},
+ [7] = {__NR_poll, 3},
#endif
- { 8, __NR_lseek, 3},
- //{ 9, __NR_mmap, 6}, // wrapped to track mmap
- //{ 10, __NR_mprotect, 3}, // same
- //{ 11, __NR_munmap, 2}, // same
- { 12, __NR_brk, 1},
- //{ 13, __NR_rt_sigaction, 4}, // wrapped to use my_ version
- { 14, __NR_rt_sigprocmask, 4},
- { 16, __NR_ioctl, 3},
- { 17, __NR_pread64, 4},
- { 18, __NR_pwrite64, 4},
- { 20, __NR_writev, 3},
+ [8] = {__NR_lseek, 3},
+ //[9] = {__NR_mmap, 6}, // wrapped to track mmap
+ //[10] = {__NR_mprotect, 3}, // same
+ //[11] = {__NR_munmap, 2}, // same
+ [12] = {__NR_brk, 1},
+ //[13] = {__NR_rt_sigaction, 4}, // wrapped to use my_ version
+ [14] = {__NR_rt_sigprocmask, 4},
+ [16] = {__NR_ioctl, 3},
+ [17] = {__NR_pread64, 4},
+ [18] = {__NR_pwrite64, 4},
+ [20] = {__NR_writev, 3},
#ifdef __NR_access
- { 21, __NR_access, 2},
+ [21] = {__NR_access, 2},
#endif
#ifdef __NR_pipe
- { 22, __NR_pipe, 1},
+ [22] = {__NR_pipe, 1},
#endif
- { 24, __NR_sched_yield, 0},
+ [24] = {__NR_sched_yield, 0},
#ifdef __NR_select
- { 23, __NR_select, 5},
+ [23] = {__NR_select, 5},
#endif
- //{ 25, __NR_mremap, 5}, // wrapped to track protection
- { 27, __NR_mincore, 3},
- { 28, __NR_madvise, 3},
+ //[25] = {__NR_mremap, 5}, // wrapped to track protection
+ [27] = {__NR_mincore, 3},
+ [28] = {__NR_madvise, 3},
#ifdef __NR_dup2
- { 33, __NR_dup2, 2},
+ [33] = {__NR_dup2, 2},
#endif
- { 35, __NR_nanosleep, 2},
- { 39, __NR_getpid, 0},
- { 41, __NR_socket, 3},
- { 42, __NR_connect, 3},
- { 43, __NR_accept, 3},
- { 44, __NR_sendto, 6},
- { 45, __NR_recvfrom, 6},
- { 46, __NR_sendmsg, 3},
- { 47, __NR_recvmsg, 3},
- { 49, __NR_bind, 3},
- { 50, __NR_listen, 2},
- { 51, __NR_getsockname, 3},
- { 52, __NR_getpeername, 3},
- { 53, __NR_socketpair, 4},
- { 54, __NR_setsockopt, 5},
- { 55, __NR_getsockopt, 5},
- //{56, __NR_clone, 5},
+ [35] = {__NR_nanosleep, 2},
+ [39] = {__NR_getpid, 0},
+ [41] = {__NR_socket, 3},
+ [42] = {__NR_connect, 3},
+ [43] = {__NR_accept, 3},
+ [44] = {__NR_sendto, 6},
+ [45] = {__NR_recvfrom, 6},
+ [46] = {__NR_sendmsg, 3},
+ [47] = {__NR_recvmsg, 3},
+ [49] = {__NR_bind, 3},
+ [50] = {__NR_listen, 2},
+ [51] = {__NR_getsockname, 3},
+ [52] = {__NR_getpeername, 3},
+ [53] = {__NR_socketpair, 4},
+ [54] = {__NR_setsockopt, 5},
+ [55] = {__NR_getsockopt, 5},
+ //[56] = {__NR_clone, 5},
#ifdef __NR_fork
- { 57, __NR_fork, 0 }, // should wrap this one, because of the struct pt_regs (the only arg)?
+ [57] = {__NR_fork, 0 }, // should wrap this one, because of the struct pt_regs (the only arg)?
#endif
- //{58, __NR_vfork, 0},
- //{59, __NR_execve, 3},
- { 60, __NR_exit, 1}, // Nees wrapping?
- { 61, __NR_wait4, 4},
- { 62, __NR_kill, 2 },
- //{ 63, __NR_uname, 1}, // Needs wrapping, use old_utsname
- { 66, __NR_semctl, 4},
- //{ 72, __NR_fnctl, 3}, // Needs wrapping, and not always defined anyway
- { 73, __NR_flock, 2},
- { 74, __NR_fsync, 1},
+ //[58] = {__NR_vfork, 0},
+ //[59] = {__NR_execve, 3},
+ [60] = {__NR_exit, 1}, // Nees wrapping?
+ [61] = {__NR_wait4, 4},
+ [62] = {__NR_kill, 2 },
+ //[63] = {__NR_uname, 1}, // Needs wrapping, use old_utsname
+ [66] = {__NR_semctl, 4},
+ //[72] = {__NR_fnctl, 3}, // Needs wrapping, and not always defined anyway
+ [73] = {__NR_flock, 2},
+ [74] = {__NR_fsync, 1},
#ifdef __NR_getdents
- { 78, __NR_getdents, 3},
+ [78] = {__NR_getdents, 3},
#endif
- { 79, __NR_getcwd, 2},
- { 80, __NR_chdir, 1},
+ [79] = {__NR_getcwd, 2},
+ [80] = {__NR_chdir, 1},
#ifdef __NR_rename
- { 82, __NR_rename, 2},
+ [82] = {__NR_rename, 2},
#endif
#ifdef __NR_mkdir
- { 83, __NR_mkdir, 2},
+ [83] = {__NR_mkdir, 2},
#endif
#ifdef __NR_unlink
- { 87, __NR_unlink, 1},
+ [87] = {__NR_unlink, 1},
#endif
- //{ 89, __NR_readlink, 3}, // not always existing, better use the wrapped version anyway
- { 96, __NR_gettimeofday, 2},
- { 97, __NR_getrlimit, 2},
- { 101, __NR_ptrace, 4},
- { 102, __NR_getuid, 0},
- { 104, __NR_getgid, 0},
- { 105, __NR_setuid, 1},
- { 106, __NR_setgid, 1},
- { 107, __NR_geteuid, 0},
- { 108, __NR_getegid, 0},
- { 109, __NR_setpgid, 2},
- { 110, __NR_getppid, 0},
- //{ 111, __NR_getpgrp, 0},
- { 112, __NR_setsid, 0},
- { 113, __NR_setreuid, 2},
- { 114, __NR_setregid, 2},
- { 118, __NR_getresuid, 3},
- { 120, __NR_getresgid, 3},
- { 125, __NR_capget, 2},
- { 126, __NR_capset, 2},
- { 127, __NR_rt_sigpending, 2},
- { 128, __NR_rt_sigtimedwait, 4},
- //{ 131, __NR_sigaltstack, 2}, // wrapped to use my_sigaltstack*
- { 140, __NR_getpriority, 2},
- { 155, __NR_pivot_root, 2},
- { 157, __NR_prctl, 5 }, // needs wrapping?
- //{ 158, __NR_arch_prctl, 2}, //need wrapping
- { 160, __NR_setrlimit, 2},
- { 161, __NR_chroot, 1},
- { 186, __NR_gettid, 0 }, //0xBA
- { 200, __NR_tkill, 2 },
+ //[89] = {__NR_readlink, 3}, // not always existing, better use the wrapped version anyway
+ [96] = {__NR_gettimeofday, 2},
+ [97] = {__NR_getrlimit, 2},
+ [101] = {__NR_ptrace, 4},
+ [102] = {__NR_getuid, 0},
+ [104] = {__NR_getgid, 0},
+ [105] = {__NR_setuid, 1},
+ [106] = {__NR_setgid, 1},
+ [107] = {__NR_geteuid, 0},
+ [108] = {__NR_getegid, 0},
+ [109] = {__NR_setpgid, 2},
+ [110] = {__NR_getppid, 0},
+ //[111] = {__NR_getpgrp, 0},
+ [112] = {__NR_setsid, 0},
+ [113] = {__NR_setreuid, 2},
+ [114] = {__NR_setregid, 2},
+ [118] = {__NR_getresuid, 3},
+ [120] = {__NR_getresgid, 3},
+ [125] = {__NR_capget, 2},
+ [126] = {__NR_capset, 2},
+ [127] = {__NR_rt_sigpending, 2},
+ [128] = {__NR_rt_sigtimedwait, 4},
+ //[131] = {__NR_sigaltstack, 2}, // wrapped to use my_sigaltstack*
+ [140] = {__NR_getpriority, 2},
+ [155] = {__NR_pivot_root, 2},
+ [157] = {__NR_prctl, 5 }, // needs wrapping?
+ //[158] = {__NR_arch_prctl, 2}, //need wrapping
+ [160] = {__NR_setrlimit, 2},
+ [161] = {__NR_chroot, 1},
+ [186] = {__NR_gettid, 0 }, //0xBA
+ [200] = {__NR_tkill, 2 },
#ifdef __NR_time
- { 201, __NR_time, 1},
+ [201] = {__NR_time, 1},
#endif
- { 202, __NR_futex, 6},
- { 203, __NR_sched_setaffinity, 3},
- { 204, __NR_sched_getaffinity, 3},
- { 206, __NR_io_setup, 2},
- { 207, __NR_io_destroy, 1},
- { 208, __NR_io_getevents, 4},
- { 209, __NR_io_submit, 3},
- { 210, __NR_io_cancel, 3},
- { 212, __NR_lookup_dcookie, 3},
+ [202] = {__NR_futex, 6},
+ [203] = {__NR_sched_setaffinity, 3},
+ [204] = {__NR_sched_getaffinity, 3},
+ [206] = {__NR_io_setup, 2},
+ [207] = {__NR_io_destroy, 1},
+ [208] = {__NR_io_getevents, 4},
+ [209] = {__NR_io_submit, 3},
+ [210] = {__NR_io_cancel, 3},
+ [212] = {__NR_lookup_dcookie, 3},
#ifdef __NR_epoll_create
- { 213, __NR_epoll_create, 1},
+ [213] = {__NR_epoll_create, 1},
#endif
- { 217, __NR_getdents64, 3},
- { 218, __NR_set_tid_address, 1},
- { 220, __NR_semtimedop, 4},
- { 228, __NR_clock_gettime, 2},
- { 229, __NR_clock_getres, 2},
- { 230, __NR_clock_nanosleep, 4},
- { 231, __NR_exit_group, 1},
+ [217] = {__NR_getdents64, 3},
+ [218] = {__NR_set_tid_address, 1},
+ [220] = {__NR_semtimedop, 4},
+ [228] = {__NR_clock_gettime, 2},
+ [229] = {__NR_clock_getres, 2},
+ [230] = {__NR_clock_nanosleep, 4},
+ [231] = {__NR_exit_group, 1},
#if defined(__NR_epoll_wait) && defined(NOALIGN)
- { 232, __NR_epoll_wait, 4},
+ [232] = {__NR_epoll_wait, 4},
#endif
#if defined(__NR_epoll_ctl) && defined(NOALIGN)
- { 233, __NR_epoll_ctl, 4},
+ [233] = {__NR_epoll_ctl, 4},
#endif
- { 234, __NR_tgkill, 3},
- { 238, __NR_set_mempolicy, 3},
- { 239, __NR_get_mempolicy, 5},
- { 247, __NR_waitid, 5},
+ [234] = {__NR_tgkill, 3},
+ [238] = {__NR_set_mempolicy, 3},
+ [239] = {__NR_get_mempolicy, 5},
+ [247] = {__NR_waitid, 5},
#ifdef __NR_inotify_init
- { 253, __NR_inotify_init, 0}, //0xFD
+ [253] = {__NR_inotify_init, 0}, //0xFD
#endif
- { 254, __NR_inotify_add_watch, 3},
- { 255, __NR_inotify_rm_watch, 2},
+ [254] = {__NR_inotify_add_watch, 3},
+ [255] = {__NR_inotify_rm_watch, 2},
#ifdef NOALIGN
- { 257, __NR_openat, 4},
+ [257] = {__NR_openat, 4},
#endif
- { 258, __NR_mkdirat, 3},
- //{ 262, __NR_fstatat, 4},
- { 263, __NR_unlinkat, 3},
+ [258] = {__NR_mkdirat, 3},
+ //[262] = {__NR_fstatat, 4},
+ [263] = {__NR_unlinkat, 3},
#ifdef __NR_renameat
- { 264, __NR_renameat, 4},
+ [264] = {__NR_renameat, 4},
#endif
- { 267, __NR_readlinkat, 4},
- { 268, __NR_fchmodat, 3},
- { 270, __NR_pselect6, 6},
- { 272, __NR_unshare, 1},
- { 273, __NR_set_robust_list, 2},
- { 274, __NR_get_robust_list, 3},
+ [266] = {__NR_symlinkat, 3},
+ [267] = {__NR_readlinkat, 4},
+ [268] = {__NR_fchmodat, 3},
+ [270] = {__NR_pselect6, 6},
+ [272] = {__NR_unshare, 1},
+ [273] = {__NR_set_robust_list, 2},
+ [274] = {__NR_get_robust_list, 3},
#ifdef NOALIGN
- { 281, __NR_epoll_pwait, 6},
+ [281] = {__NR_epoll_pwait, 6},
#endif
+ //[282] = {__NR__signalfd, 3},
#ifdef _NR_eventfd
- { 284, __NR_eventfd, 1},
+ [284] = {__NR_eventfd, 1},
#endif
- { 285, __NR_fallocate, 4},
- { 288, __NR_accept4, 4},
- { 290, __NR_eventfd2, 2},
- { 291, __NR_epoll_create1, 1},
- { 292, __NR_dup3, 3},
- { 293, __NR_pipe2, 2},
- { 294, __NR_inotify_init1, 1},
- { 297, __NR_rt_tgsigqueueinfo, 4},
- { 298, __NR_perf_event_open, 5},
- { 302, __NR_prlimit64, 4},
- { 309, __NR_getcpu, 3}, // need wrapping?
- { 315, __NR_sched_getattr, 4},
- //{ 317, __NR_seccomp, 3},
- { 318, __NR_getrandom, 3},
- { 319, __NR_memfd_create, 2},
- { 324, __NR_membarrier, 2},
+ [285] = {__NR_fallocate, 4},
+ [288] = {__NR_accept4, 4},
+ [290] = {__NR_eventfd2, 2},
+ [291] = {__NR_epoll_create1, 1},
+ [292] = {__NR_dup3, 3},
+ [293] = {__NR_pipe2, 2},
+ [294] = {__NR_inotify_init1, 1},
+ [297] = {__NR_rt_tgsigqueueinfo, 4},
+ [298] = {__NR_perf_event_open, 5},
+ [302] = {__NR_prlimit64, 4},
+ [309] = {__NR_getcpu, 3}, // need wrapping?
+ [315] = {__NR_sched_getattr, 4},
+ //[317] = {__NR_seccomp, 3},
+ [318] = {__NR_getrandom, 3},
+ [319] = {__NR_memfd_create, 2},
+ [324] = {__NR_membarrier, 2},
#ifdef __NR_statx
// TODO: implement fallback if __NR_statx is not defined
- { 332, __NR_statx, 5},
+ [332] = {__NR_statx, 5},
#endif
#ifdef __NR_fchmodat4
- { 434, __NR_fchmodat4, 4},
- #endif
- #ifdef __NR_futex_waitv
- { 449, __NR_futex_waitv, 5},
+ [434] = {__NR_fchmodat4, 4},
#endif
+ //[449] = {__NR_futex_waitv, 5},
};
struct mmap_arg_struct {
@@ -397,90 +398,88 @@ void EXPORT x64Syscall(x64emu_t *emu)
}
// check wrapper first
int cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
- for (int i=0; i<cnt; i++) {
- if(syscallwrap[i].x64s == s) {
- int sc = syscallwrap[i].nats;
- switch(syscallwrap[i].nbpars) {
- case 0: *(int64_t*)&R_RAX = syscall(sc); break;
- case 1: *(int64_t*)&R_RAX = syscall(sc, R_RDI); break;
- case 2: if(s==33) {if(log) snprintf(buff2, 63, " [sys_access(\"%s\", %ld)]", (char*)R_RDI, R_RSI);}; *(int64_t*)&R_RAX = syscall(sc, R_RDI, R_RSI); break;
- case 3: if(s==42) {if(log) snprintf(buff2, 63, " [sys_connect(%d, %p[type=%d], %d)]", R_EDI, (void*)R_RSI, *(unsigned short*)R_RSI, R_EDX);}; if(s==258) {if(log) snprintf(buff2, 63, " [sys_mkdirat(%d, %s, 0x%x]", R_EDI, (char*)R_RSI, R_EDX);}; *(int64_t*)&R_RAX = syscall(sc, R_RDI, R_RSI, R_RDX); break;
- case 4: *(int64_t*)&R_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10); break;
- case 5: *(int64_t*)&R_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10, R_R8); break;
- case 6: *(int64_t*)&R_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10, R_R8, R_R9); break;
- default:
- printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[i].nbpars);
- emu->quit = 1;
- return;
- }
- if(R_EAX==0xffffffff && errno>0)
- R_RAX = (uint64_t)-errno;
- if(log) snprintf(buffret, 127, "0x%x%s", R_EAX, buff2);
- if(log && !cycle_log) printf_log(LOG_NONE, "=> %s\n", buffret);
- return;
+ if(s<cnt && syscallwrap[s].nats) {
+ int sc = syscallwrap[s].nats;
+ switch(syscallwrap[s].nbpars) {
+ case 0: S_RAX = syscall(sc); break;
+ case 1: S_RAX = syscall(sc, R_RDI); break;
+ case 2: if(s==33) {if(log) snprintf(buff2, 63, " [sys_access(\"%s\", %ld)]", (char*)R_RDI, R_RSI);}; S_RAX = syscall(sc, R_RDI, R_RSI); break;
+ case 3: if(s==42) {if(log) snprintf(buff2, 63, " [sys_connect(%d, %p[type=%d], %d)]", R_EDI, (void*)R_RSI, *(unsigned short*)R_RSI, R_EDX);}; if(s==258) {if(log) snprintf(buff2, 63, " [sys_mkdirat(%d, %s, 0x%x]", R_EDI, (char*)R_RSI, R_EDX);}; S_RAX = syscall(sc, R_RDI, R_RSI, R_RDX); break;
+ case 4: S_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10); break;
+ case 5: S_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10, R_R8); break;
+ case 6: S_RAX = syscall(sc, R_RDI, R_RSI, R_RDX, R_R10, R_R8, R_R9); break;
+ default:
+ printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[s].nbpars);
+ emu->quit = 1;
+ return;
}
+ if(S_RAX==-1 && errno>0)
+ S_RAX = -errno;
+ if(log) snprintf(buffret, 127, "0x%x%s", R_EAX, buff2);
+ if(log && !cycle_log) printf_log(LOG_NONE, "=> %s\n", buffret);
+ return;
}
switch (s) {
case 0: // sys_read
- *(int64_t*)&R_RAX = read((int)R_EDI, (void*)R_RSI, (size_t)R_RDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = read(S_EDI, (void*)R_RSI, (size_t)R_RDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 1: // sys_write
- *(int64_t*)&R_RAX = write((int)R_EDI, (void*)R_RSI, (size_t)R_RDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = write(S_EDI, (void*)R_RSI, (size_t)R_RDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 2: // sys_open
if(s==5) {if (log) snprintf(buff2, 63, " [sys_open(\"%s\", %d, %d)]", (char*)R_RDI, of_convert(R_ESI), R_EDX);};
- //*(int64_t*)&R_RAX = open((void*)R_EDI, of_convert(R_ESI), R_EDX);
- *(int64_t*)&R_RAX = my_open(emu, (void*)R_RDI, of_convert(R_ESI), R_EDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ //S_RAX = open((void*)R_EDI, of_convert(R_ESI), R_EDX);
+ S_RAX = my_open(emu, (void*)R_RDI, of_convert(R_ESI), R_EDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 3: // sys_close
- *(int64_t*)&R_RAX = close((int)R_EDI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = close(S_EDI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 4: // sys_stat
- *(int64_t*)&R_RAX = my_stat(emu, (void*)R_RDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_stat(emu, (void*)R_RDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 5: // sys_fstat
- *(int64_t*)&R_RAX = my_fstat(emu, (int)R_EDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_fstat(emu, S_EDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 6: // sys_lstat
- *(int64_t*)&R_RAX = my_lstat(emu, (void*)R_RDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_lstat(emu, (void*)R_RDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#ifndef __NR_poll
case 7: // sys_poll
- *(int64_t*)&R_RAX = poll((struct pollfd*)R_RDI, (nfds_t)R_RSI, (int)R_EDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = poll((struct pollfd*)R_RDI, (nfds_t)R_RSI, S_EDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 9: // sys_mmap
- R_RAX = (uintptr_t)my_mmap64(emu, (void*)R_RDI, R_RSI, (int)R_EDX, (int)R_R10d, (int)R_R8d, R_R9);
+ R_RAX = (uintptr_t)my_mmap64(emu, (void*)R_RDI, R_RSI, S_EDX, S_R10d, S_R8d, R_R9);
break;
case 10: // sys_mprotect
- *(int64_t*)&R_RAX = my_mprotect(emu, (void*)R_RDI, R_RSI, (int)R_EDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_mprotect(emu, (void*)R_RDI, R_RSI, S_EDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 11: // sys_munmap
- *(int64_t*)&R_RAX = my_munmap(emu, (void*)R_RDI, R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_munmap(emu, (void*)R_RDI, R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 13: // sys_rt_sigaction
#if 1
- R_RAX = (int64_t)my_syscall_rt_sigaction(emu, (int)R_EDI, (const x64_sigaction_restorer_t *)R_RSI, (x64_sigaction_restorer_t *)R_RDX, (size_t)R_R10);
+ S_RAX = my_syscall_rt_sigaction(emu, S_EDI, (const x64_sigaction_restorer_t *)R_RSI, (x64_sigaction_restorer_t *)R_RDX, (size_t)R_R10);
#else
{
x64_sigaction_t n ={0};
@@ -492,7 +491,7 @@ void EXPORT x64Syscall(x64emu_t *emu)
n.sa_restorer = p->sa_restorer;
memcpy(&n.sa_mask, &p->sa_mask, R_R10);
}
- R_RAX = (int64_t)(int64_t)my_sigaction(emu, (int)R_EDI, R_RSI?&n:NULL, R_RDX?&o:NULL/*, (size_t)R_R10*/);
+ R_RAX = (int64_t)(int64_t)my_sigaction(emu, S_EDI, R_RSI?&n:NULL, R_RDX?&o:NULL/*, (size_t)R_R10*/);
if(R_RAX>=0 && R_RDX) {
x64_sigaction_restorer_t *p = (x64_sigaction_restorer_t*)R_RDX;
p->_u._sa_sigaction = o._u._sa_sigaction;
@@ -502,28 +501,28 @@ void EXPORT x64Syscall(x64emu_t *emu)
}
}
#endif
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#ifndef __NR_access
case 21: // sys_access
- *(int64_t*)&R_RAX = access((void*)R_RDI, R_ESI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = access((void*)R_RDI, R_ESI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef __NR_pipe
case 22:
- *(int64_t*)&R_RAX = pipe((void*)R_RDI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = pipe((void*)R_RDI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef __NR_select
case 23: // sys_select
- R_EAX = (uint32_t)select(R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_R10, (void*)R_R8);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = select(R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_R10, (void*)R_R8);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 25: // sys_mremap
@@ -531,9 +530,9 @@ void EXPORT x64Syscall(x64emu_t *emu)
break;
#ifndef __NR_dup2
case 33: // sys_dup2
- R_EAX = (uint32_t)dup2((int)R_EDI, (int)R_ESI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = dup2(S_EDI, S_ESI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 56: // sys_clone
@@ -541,9 +540,9 @@ void EXPORT x64Syscall(x64emu_t *emu)
// so flags=R_RDI, stack=R_RSI, parent_tid=R_RDX, child_tid=R_R10, tls=R_R8
if((R_EDI&~0xff)==0x4100) {
// this is a case of vfork...
- R_EAX = my_vfork(emu);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_vfork(emu);
+ if(S_RAX==-1)
+ S_RAX = -errno;
} else {
if(R_RSI)
{
@@ -579,54 +578,48 @@ void EXPORT x64Syscall(x64emu_t *emu)
my_context->stack_clone_used = 1;
}
int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_RDI, newemu, R_RDX, R_R8, R_R10);
- R_RAX = (uint64_t)ret;
+ S_RAX = ret;
}
else
#ifdef NOALIGN
- R_RAX = (uint64_t)syscall(__NR_clone, R_RDI, R_RSI, R_RDX, R_R10, R_R8);
+ S_RAX = syscall(__NR_clone, R_RDI, R_RSI, R_RDX, R_R10, R_R8);
#else
- R_RAX = (uint64_t)syscall(__NR_clone, R_RDI, R_RSI, R_RDX, R_R8, R_R10); // invert R_R8/R_R10 on Aarch64 and most other
+ S_RAX = syscall(__NR_clone, R_RDI, R_RSI, R_RDX, R_R8, R_R10); // invert R_R8/R_R10 on Aarch64 and most other
#endif
}
break;
#ifndef __NR_fork
case 57:
- R_RAX = fork();
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = fork();
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 58: // vfork
- {
- int64_t r = my_vfork(emu);
- R_RAX = r;
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
- }
+ S_RAX = my_vfork(emu);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 59: // execve
- {
- int64_t r = my_execve(emu, (const char*)R_RDI, (char* const*)R_RSI, (char* const*)R_RDX);
- R_RAX = r;
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
- }
+ S_RAX = my_execve(emu, (const char*)R_RDI, (char* const*)R_RSI, (char* const*)R_RDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 63: //uname
{
old_utsname_t *old = (old_utsname_t*)R_RDI;
struct utsname uts;
- R_RAX = uname(&uts);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = uname(&uts);
+ if(S_RAX==-1)
+ S_RAX = -errno;
memcpy(old, &uts, sizeof(*old)); // old_uts is just missing a field from new_uts
strcpy(old->machine, "x86_64");
}
break;
case 72: //fcntl
- R_RAX = (uint64_t)my_fcntl(emu, (int)R_EDI, (int)R_ESI, (void*)R_RDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_fcntl(emu, S_EDI, S_ESI, (void*)R_RDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#ifndef __NR_getdents
case 78:
@@ -643,94 +636,113 @@ void EXPORT x64Syscall(x64emu_t *emu)
#endif
#ifndef __NR_rename
case 82: // sys_rename
- *(int64_t*)&R_RAX = rename((void*)R_RDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = rename((void*)R_RDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef __NR_mkdir
case 83: // sys_mkdir
- *(int64_t*)&R_RAX = mkdir((void*)R_RDI, R_ESI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = mkdir((void*)R_RDI, R_ESI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef __NR_unlink
case 87: //sys_unlink
- *(int64_t*)&R_RAX = unlink((void*)R_RDI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = unlink((void*)R_RDI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 89: // sys_readlink
- R_RAX = (ssize_t)my_readlink(emu,(void*)R_RDI, (void*)R_RSI, (size_t)R_RDX);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_readlink(emu,(void*)R_RDI, (void*)R_RSI, (size_t)R_RDX);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 131: // sys_sigaltstack
- *(int64_t*)&R_RAX = my_sigaltstack(emu, (void*)R_RDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_sigaltstack(emu, (void*)R_RDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
case 158: // sys_arch_prctl
- *(int64_t*)&R_RAX = my_arch_prctl(emu, (int)R_EDI, (void*)R_RSI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_arch_prctl(emu, S_EDI, (void*)R_RSI);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#ifndef __NR_time
case 201: // sys_time
R_RAX = (uintptr_t)time((void*)R_RDI);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#if !defined(__NR_epoll_wait) || !defined(NOALIGN)
case 232:
- R_RAX = my_epoll_wait(emu, (int)R_EDI, (void*)R_RSI, (int)R_EDX, (int)R_R10d);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ R_RAX = my_epoll_wait(emu, S_EDI, (void*)R_RSI, S_EDX, S_R10d);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#if !defined(__NR_epoll_ctl) || !defined(NOALIGN)
case 233:
- R_EAX = my_epoll_ctl(emu, (int)R_EDI, (int)R_ESI, (int)R_EDX, (void*)R_R10);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_epoll_ctl(emu, S_EDI, S_ESI, S_EDX, (void*)R_R10);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef __NR_inotify_init
case 253:
- R_EAX = (int)syscall(__NR_inotify_init1, 0);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = syscall(__NR_inotify_init1, 0);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef NOALIGN
case 257:
- R_EAX = (int)syscall(__NR_openat, (int)R_EDI, (void*)R_RSI, of_convert((int)R_EDX), R_R10d);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = syscall(__NR_openat, S_EDI, (void*)R_RSI, of_convert(S_EDX), R_R10d);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
case 262:
- R_EAX = (uint32_t)my_fstatat(emu, (int)R_RDI, (char*)R_RSI, (void*)R_RDX, (int)R_R10d);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_fstatat(emu, S_RDI, (char*)R_RSI, (void*)R_RDX, S_R10d);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#ifndef __NR_renameat
case 264:
- R_EAX = (uint32_t)renameat((int)R_RDI, (const char*)R_RSI, (int)R_EDX, (const char*)R_R10);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ R_EAX = (uint32_t)renameat(S_RDI, (const char*)R_RSI, S_EDX, (const char*)R_R10);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
#ifndef NOALIGN
case 281: // sys_epool_pwait
- R_EAX = (uint32_t)my_epoll_pwait(emu, (int)R_EDI, (void*)R_RSI, (int)R_EDX, (int)R_R10d, (void*)R_R8);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = my_epoll_pwait(emu, S_EDI, (void*)R_RSI, S_EDX, S_R10d, (void*)R_R8);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
+ case 282: // sys_signalfd
+ // need to mask SIGSEGV
+ {
+ sigset_t * set = (sigset_t *)R_RSI;
+ if(sigismember(set, SIGSEGV)) {
+ sigdelset(set, SIGSEGV);
+ printf_log(LOG_INFO, "Warning, signalfd on SIGSEGV unsuported\n");
+ }
+ S_RAX = signalfd(S_EDI, set, 0);
+ if(S_RAX==-1)
+ S_RAX = -errno;
+ }
+ break;
+ #ifndef _NR_eventfd
+ case 284: // sys_eventfd
+ S_RAX = eventfd(S_EDI, 0);
+ if(S_RAX==-1)
+ S_RAX = -errno;
+ #endif
case 317: // sys_seccomp
R_RAX = 0; // ignoring call
break;
@@ -739,11 +751,19 @@ void EXPORT x64Syscall(x64emu_t *emu)
break;
#ifndef __NR_fchmodat4
case 434:
- *(int64_t*)R_RAX = fchmodat((int)R_EDI, (void*)R_RSI, (mode_t)R_RDX, (int)R_R10d);
- if(R_EAX==0xffffffff)
- R_RAX = (uint64_t)-errno;
+ S_RAX = fchmodat(S_EDI, (void*)R_RSI, (mode_t)R_RDX, S_R10d);
+ if(S_RAX==-1)
+ S_RAX = -errno;
break;
#endif
+ case 449:
+ #ifdef __NR_futex_waitv
+ if(box64_futex_waitv)
+ S_RAX = syscall(__NR_futex_waitv, R_RDI, R_RSI, R_RDX, R_R10, R_R8);
+ else
+ #endif
+ S_RAX = -ENOSYS;
+ break;
default:
printf_log(LOG_INFO, "Error: Unsupported Syscall 0x%02Xh (%d)\n", s, s);
emu->quit = 1;
@@ -761,60 +781,58 @@ void EXPORT x64Syscall(x64emu_t *emu)
#define u64(n) *(uint64_t*)stack(n)
#define p(n) *(void**)stack(n)
-uintptr_t EXPORT my_syscall(x64emu_t *emu)
+long EXPORT my_syscall(x64emu_t *emu)
{
static uint32_t warned = 0;
uint32_t s = R_EDI;
printf_dump(LOG_DEBUG, "%04d| %p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", GetTID(), (void*)R_RIP, s, s, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
// check wrapper first
int cnt = sizeof(syscallwrap) / sizeof(scwrap_t);
- for (int i=0; i<cnt; i++) {
- if(syscallwrap[i].x64s == s) {
- int sc = syscallwrap[i].nats;
- switch(syscallwrap[i].nbpars) {
- case 0: return syscall(sc);
- case 1: return syscall(sc, R_RSI);
- case 2: return syscall(sc, R_RSI, R_RDX);
- case 3: return syscall(sc, R_RSI, R_RDX, R_RCX);
- case 4: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8);
- case 5: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8, R_R9);
- case 6: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8, R_R9, u64(0));
- default:
- printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[i].nbpars);
- emu->quit = 1;
- return 0;
- }
+ if(s<cnt && syscallwrap[s].nats) {
+ int sc = syscallwrap[s].nats;
+ switch(syscallwrap[s].nbpars) {
+ case 0: return syscall(sc);
+ case 1: return syscall(sc, R_RSI);
+ case 2: return syscall(sc, R_RSI, R_RDX);
+ case 3: return syscall(sc, R_RSI, R_RDX, R_RCX);
+ case 4: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8);
+ case 5: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8, R_R9);
+ case 6: return syscall(sc, R_RSI, R_RDX, R_RCX, R_R8, R_R9, u64(0));
+ default:
+ printf_log(LOG_NONE, "ERROR, Unimplemented syscall wrapper (%d, %d)\n", s, syscallwrap[s].nbpars);
+ emu->quit = 1;
+ return 0;
}
}
switch (s) {
case 0: // sys_read
- return (uint64_t)read(R_ESI, (void*)R_RDX, R_ECX);
+ return read(R_ESI, (void*)R_RDX, R_ECX);
case 1: // sys_write
- return (uint64_t)write(R_ESI, (void*)R_RDX, R_ECX);
+ return write(R_ESI, (void*)R_RDX, R_ECX);
case 2: // sys_open
return my_open(emu, (char*)R_RSI, of_convert(R_EDX), R_ECX);
case 3: // sys_close
- return (uint64_t)(int64_t)close(R_ESI);
+ return close(R_ESI);
case 4: // sys_stat
- return (uint64_t)(int64_t)my_stat(emu, (void*)R_RSI, (void*)R_RDX);
+ return my_stat(emu, (void*)R_RSI, (void*)R_RDX);
case 5: // sys_fstat
- return (uint64_t)(int64_t)my_fstat(emu, (int)R_ESI, (void*)R_RDX);
+ return my_fstat(emu, S_ESI, (void*)R_RDX);
case 6: // sys_lstat
- return (uint64_t)(int64_t)my_lstat(emu, (void*)R_RSI, (void*)R_RDX);
+ return my_lstat(emu, (void*)R_RSI, (void*)R_RDX);
#ifndef __NR_poll
case 7: // sys_poll
- return (uint64_t)(int64_t)poll((struct pollfd*)R_RSI, (nfds_t)R_RDX, (int)R_ECX);
+ return poll((struct pollfd*)R_RSI, (nfds_t)R_RDX, S_ECX);
break;
#endif
case 9: // sys_mmap
- return (uintptr_t)my_mmap64(emu, (void*)R_RSI, R_RDX, (int)R_RCX, (int)R_R8d, (int)R_R9, i64(0));
+ return (intptr_t)my_mmap64(emu, (void*)R_RSI, R_RDX, S_RCX, S_R8d, S_R9, i64(0));
case 10: // sys_mprotect
- return (uint64_t)my_mprotect(emu, (void*)R_RSI, R_RDX, (int)R_ECX);
+ return my_mprotect(emu, (void*)R_RSI, R_RDX, S_ECX);
case 11: // sys_munmap
- return (uint64_t)my_munmap(emu, (void*)R_RSI, R_RDX);
+ return my_munmap(emu, (void*)R_RSI, R_RDX);
case 13: // sys_rt_sigaction
#if 1
- return my_syscall_rt_sigaction(emu, (int)R_ESI, (const x64_sigaction_restorer_t *)R_RDX, (x64_sigaction_restorer_t *)R_RCX, (size_t)R_R8);
+ return my_syscall_rt_sigaction(emu, S_ESI, (const x64_sigaction_restorer_t *)R_RDX, (x64_sigaction_restorer_t *)R_RCX, (size_t)R_R8);
#else
{
x64_sigaction_t n ={0};
@@ -826,7 +844,7 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
n.sa_restorer = p->sa_restorer;
memcpy(&n.sa_mask, &p->sa_mask, R_R8);
}
- uint64_t ret = (uint64_t)(int64_t)my_sigaction(emu, (int)R_ESI, R_RDX?&n:NULL, R_RCX?&o:NULL/*, (size_t)R_R8*/);
+ long ret = my_sigaction(emu, S_ESI, R_RDX?&n:NULL, R_RCX?&o:NULL/*, (size_t)R_R8*/);
if(R_RCX) {
x64_sigaction_restorer_t *p = (x64_sigaction_restorer_t*)R_RCX;
p->_u._sa_sigaction = o._u._sa_sigaction;
@@ -839,18 +857,18 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
#endif
#ifndef __NR_access
case 21: // sys_access
- return (uint64_t)(int64_t)access((void*)R_RSI, R_EDX);
+ return access((void*)R_RSI, R_EDX);
#endif
#ifndef __NR_pipe
case 22:
- return (uint64_t)(int64_t)pipe((void*)R_RSI);
+ return pipe((void*)R_RSI);
#endif
#ifndef __NR_select
case 23: // sys_select
- return (uint64_t)(int64_t)select(R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
+ return select(R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9);
#endif
case 25: // sys_mremap
- return (uintptr_t)my_mremap(emu, (void*)R_RSI, R_RDX, R_RCX, R_R8d, (void*)R_R9);
+ return (intptr_t)my_mremap(emu, (void*)R_RSI, R_RDX, R_RCX, R_R8d, (void*)R_R9);
case 56: // sys_clone
// x86_64 raw syscall is long clone(unsigned long flags, void *stack, int *parent_tid, int *child_tid, unsigned long tls);
// so flags=R_RSI, stack=R_RDX, parent_tid=R_RCX, child_tid=R_R8, tls=R_R9
@@ -888,19 +906,19 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
my_context->stack_clone_used = 1;
}
// x86_64 raw clone is long clone(unsigned long flags, void *stack, int *parent_tid, int *child_tid, unsigned long tls);
- int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_ESI, newemu, R_RCX, R_R9, R_R8);
- return (uintptr_t)ret;
+ long ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_ESI, newemu, R_RCX, R_R9, R_R8);
+ return ret;
}
else
#ifdef NOALIGN
- return (uintptr_t)syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R8, R_R9);
+ return syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R8, R_R9);
#else
- return (uintptr_t)syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R9, R_R8); // invert R_R8/R_R9 on Aarch64 and most other
+ return syscall(__NR_clone, R_RSI, R_RDX, R_RCX, R_R9, R_R8); // invert R_R8/R_R9 on Aarch64 and most other
#endif
break;
#ifndef __NR_dup2
case 33:
- return dup2((int)R_ESI, (int)R_EDX);
+ return dup2(S_ESI, S_EDX);
#endif
#ifndef __NR_fork
case 57:
@@ -914,13 +932,13 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
{
old_utsname_t *old = (old_utsname_t*)R_RSI;
struct utsname uts;
- int64_t ret = uname(&uts);
+ long ret = uname(&uts);
memcpy(old, &uts, sizeof(*old));
strcpy(old->machine, "x86_64");
return ret;
}
case 72: //fcntl
- R_RAX = (uint64_t)my_fcntl(emu, (int)R_ESI, (int)R_EDX, (void*)R_RCX);
+ R_RAX = (uint64_t)my_fcntl(emu, S_ESI, S_EDX, (void*)R_RCX);
break;
#ifndef __NR_getdents
case 78:
@@ -929,63 +947,86 @@ uintptr_t EXPORT my_syscall(x64emu_t *emu)
nat_linux_dirent64_t *d64 = (nat_linux_dirent64_t*)alloca(count);
ssize_t ret = syscall(__NR_getdents64, R_ESI, d64, count);
ret = DirentFromDirent64((void*)R_RDX, d64, ret);
- return (uint64_t)ret;
+ return ret;
}
#endif
#ifndef __NR_mkdir
case 83: // sys_mkdir
- return (uint64_t)(int64_t)mkdir((void*)R_RSI, R_EDX);
+ return mkdir((void*)R_RSI, R_EDX);
#endif
#ifndef __NR_unlink
case 87: //sys_unlink
- return (uint64_t)(int64_t)unlink((void*)R_RSI);
+ return unlink((void*)R_RSI);
#endif
case 89: // sys_readlink
- return (uintptr_t)my_readlink(emu,(void*)R_RSI, (void*)R_RDX, (size_t)R_RCX);
+ return my_readlink(emu,(void*)R_RSI, (void*)R_RDX, (size_t)R_RCX);
case 131: // sys_sigaltstack
- return (uint64_t)(int64_t)my_sigaltstack(emu, (void*)R_RSI, (void*)R_RDX);
+ return my_sigaltstack(emu, (void*)R_RSI, (void*)R_RDX);
case 158: // sys_arch_prctl
- return (uint64_t)(int64_t)my_arch_prctl(emu, (int)R_ESI, (void*)R_RDX);
+ return my_arch_prctl(emu, S_ESI, (void*)R_RDX);
#ifndef __NR_time
case 201: // sys_time
- return (uintptr_t)time((void*)R_RSI);
+ return (intptr_t)time((void*)R_RSI);
#endif
#if !defined(__NR_epoll_wait) || !defined(NOALIGN)
case 232:
- R_RAX = my_epoll_wait(emu, (int)R_ESI, (void*)R_RDX, (int)R_ECX, (int)R_R8d);
- break;
+ return my_epoll_wait(emu, S_ESI, (void*)R_RDX, S_ECX, S_R8d);
#endif
#if !defined(__NR_epoll_ctl) || !defined(NOALIGN)
case 233:
- R_EAX = my_epoll_ctl(emu, (int)R_ESI, (int)R_EDX, (int)R_ECX, (void*)R_R8);
- break;
+ return my_epoll_ctl(emu, S_ESI, S_EDX, S_ECX, (void*)R_R8);
#endif
#ifndef __NR_inotify_init
case 253:
- return (int)syscall(__NR_inotify_init1, 0);
+ return syscall(__NR_inotify_init1, 0);
#endif
#ifndef NOALIGN
case 257:
- R_EAX = (int)syscall(__NR_openat, (int)R_ESI, (void*)R_RDX, of_convert((int)R_ECX), R_R8d);
- break;
+ syscall(__NR_openat, S_ESI, (void*)R_RDX, of_convert(S_ECX), R_R8d);
#endif
case 262:
- return (uint64_t)(int64_t)my_fstatat(emu, (int)R_RSI, (char*)R_RDX, (void*)R_RCX, (int)R_R8d);
+ return my_fstatat(emu, S_RSI, (char*)R_RDX, (void*)R_RCX, S_R8d);
#ifndef __NR_renameat
case 264:
- return (uint64_t)(int64_t)renameat((int)R_RSI, (const char*)R_RDX, (int)R_ECX, (const char*)R_R8);
+ return renameat(S_RSI, (const char*)R_RDX, S_ECX, (const char*)R_R8);
#endif
#ifndef NOALIGN
case 281: // sys_epool_pwait
- return (uint64_t)(int64_t)my_epoll_pwait(emu, (int)R_ESI, (void*)R_RDX, (int)R_ECX, (int)R_R8d, (void*)R_R9);
+ return my_epoll_pwait(emu, S_ESI, (void*)R_RDX, S_ECX, S_R8d, (void*)R_R9);
break;
#endif
+ case 282: // sys_signalfd
+ // need to mask SIGSEGV
+ {
+ sigset_t * set = (sigset_t *)R_RDX;
+ if(sigismember(set, SIGSEGV)) {
+ sigdelset(set, SIGSEGV);
+ printf_log(LOG_INFO, "Warning, signalfd on SIGSEGV unsuported\n");
+ }
+ return signalfd(S_ESI, set, 0);
+ }
+ break;
+ #ifndef _NR_eventfd
+ case 284: // sys_eventfd
+ return eventfd(S_ESI, 0);
+ #endif
case 317: // sys_seccomp
return 0; // ignoring call
#ifndef __NR_fchmodat4
case 434:
- return (int)fchmodat((int)R_ESI, (void*)R_RDX, (mode_t)R_RCX, (int)R_R8d);
+ return fchmodat(S_ESI, (void*)R_RDX, (mode_t)R_RCX, S_R8d);
#endif
+ case 449:
+ #ifdef __NR_futex_waitv
+ if(box64_futex_waitv)
+ return syscall(__NR_futex_waitv, R_RSI, R_RDX, R_RCX, R_R8, R_R9);
+ else
+ #endif
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+ break;
default:
if(!(warned&(1<<s))) {
printf_log(LOG_INFO, "Warning: Unsupported libc Syscall 0x%02X (%d)\n", s, s);
diff --git a/src/emu/x64test.c b/src/emu/x64test.c
index 8e0327a..94bdd55 100644
--- a/src/emu/x64test.c
+++ b/src/emu/x64test.c
@@ -24,9 +24,9 @@
void print_banner(x64emu_t* ref)
{
- printf_log(LOG_NONE, "Warning, difference between Interpreter and Dynarec in %p (%02x %02x %02x %02x %02x %02x %02x %02x)\n"\
+ printf_log(LOG_NONE, "Warning, difference between %s Interpreter and Dynarec in %p (%02x %02x %02x %02x %02x %02x %02x %02x)\n"\
"=======================================\n",
- (void*)ref->old_ip,
+ (ref->segs[_CS]==0x23)?"x86":"x64" ,(void*)ref->old_ip,
((uint8_t*)ref->old_ip)[0], ((uint8_t*)ref->old_ip)[1], ((uint8_t*)ref->old_ip)[2], ((uint8_t*)ref->old_ip)[3],
((uint8_t*)ref->old_ip)[4], ((uint8_t*)ref->old_ip)[5], ((uint8_t*)ref->old_ip)[6], ((uint8_t*)ref->old_ip)[7]
);
diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c
index 83fc1f6..991f0b1 100644
--- a/src/emu/x64tls.c
+++ b/src/emu/x64tls.c
@@ -152,6 +152,7 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr)
#define ARCH_GET_GS 0x1004
int seg = 0;
int idx = 0;
+ errno = 0;
switch(code) {
case ARCH_GET_GS:
*(void**)addr = GetSegmentBase(emu->segs[_GS]);
@@ -281,7 +282,9 @@ static void* resizeTLSData(box64context_t *context, void* oldptr)
mutex_lock(&context->mutex_tls);
tlsdatasize_t* oldata = (tlsdatasize_t*)oldptr;
if(sizeTLSData(oldata->tlssize)!=sizeTLSData(context->tlssize) || (oldata->n_elfs/0xff)!=(context->elfsize/0xff)) {
- printf_log(LOG_INFO, "Warning, resizing of TLS occurred! size: %d->%d / n_elfs: %d->%d\n", sizeTLSData(oldata->tlssize), sizeTLSData(context->tlssize), 1+(oldata->n_elfs/0xff), 1+(context->elfsize/0xff));
+ if(sizeTLSData(oldata->tlssize)) {
+ printf_log(LOG_INFO, "Warning, resizing of TLS occurred! size: %d->%d / n_elfs: %d->%d\n", sizeTLSData(oldata->tlssize), sizeTLSData(context->tlssize), 1+(oldata->n_elfs/0xff), 1+(context->elfsize/0xff));
+ }
tlsdatasize_t *data = setupTLSData(context);
// copy the relevent old part, in case something changed
memcpy((void*)((uintptr_t)data->data-oldata->tlssize), (void*)((uintptr_t)oldata->data-oldata->tlssize), oldata->tlssize);
diff --git a/src/emu/x86syscall.c b/src/emu/x86syscall.c
index b41b006..b3f7287 100755
--- a/src/emu/x86syscall.c
+++ b/src/emu/x86syscall.c
@@ -43,7 +43,7 @@ typedef struct scwrap_s {
int nbpars;
} scwrap_t;
-static scwrap_t syscallwrap[] = {
+static const scwrap_t syscallwrap[] = {
//{ 2, __NR_fork, 1 },
//{ 3, __NR_read, 3 }, // wrapped so SA_RESTART can be handled by libc
//{ 4, __NR_write, 3 }, // same
diff --git a/src/emu/x87emu_private.h b/src/emu/x87emu_private.h
index 5721088..a8e2d39 100644
--- a/src/emu/x87emu_private.h
+++ b/src/emu/x87emu_private.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <math.h>
+#include <fenv.h>
#include "regs.h"
#include "x64run_private.h"
#include "debug.h"
@@ -108,8 +109,13 @@ static inline double fpu_round(x64emu_t* emu, double d) {
if (!isfinite(d))
return d;
switch(emu->cw.f.C87_RD) {
- case ROUND_Nearest:
- return nearbyint(d);
+ case ROUND_Nearest: {
+ int round = fegetround();
+ fesetround(FE_TONEAREST);
+ double res = nearbyint(d);
+ fesetround(round);
+ return res;
+ }
case ROUND_Down:
return floor(d);
case ROUND_Up:
diff --git a/src/include/box64context.h b/src/include/box64context.h
index aa8c95b..9644203 100644
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -59,6 +59,7 @@ typedef struct needed_libs_s {
int size;
char** names;
library_t** libs;
+ int nb_done;
} needed_libs_t;
void free_neededlib(needed_libs_t* needed);
@@ -197,10 +198,10 @@ typedef struct box64context_s {
uint8_t canary[8];
- uintptr_t signals[MAX_SIGNAL];
- uintptr_t restorer[MAX_SIGNAL];
- int onstack[MAX_SIGNAL];
- int is_sigaction[MAX_SIGNAL];
+ uintptr_t signals[MAX_SIGNAL+1]; // signal should be 1..MAX_SIGNAL (no 0), but that's too much change...
+ uintptr_t restorer[MAX_SIGNAL+1];
+ int onstack[MAX_SIGNAL+1];
+ int is_sigaction[MAX_SIGNAL+1];
x64emu_t *emu_sig; // the emu with stack used for signal handling (must be separated from main ones)
int no_sigsegv;
int no_sigill;
diff --git a/src/include/bridge.h b/src/include/bridge.h
index 0c23808..1197ac7 100644
--- a/src/include/bridge.h
+++ b/src/include/bridge.h
@@ -23,10 +23,7 @@ int hasAlternate(void* addr);
void* getAlternate(void* addr);
void addAlternate(void* addr, void* alt);
void cleanAlternate(void);
-
-#ifdef HAVE_TRACE
const char* getBridgeName(void* addr);
-#endif
void init_bridge_helper(void);
void fini_bridge_helper(void);
diff --git a/src/include/custommem.h b/src/include/custommem.h
index 13e73c4..60fabce 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -36,6 +36,23 @@ uintptr_t getJumpTable64(void);
uintptr_t getJumpTableAddress64(uintptr_t addr);
uintptr_t getJumpAddress64(uintptr_t addr);
+#ifdef SAVE_MEM
+#define JMPTABL_SHIFT4 16
+#define JMPTABL_SHIFT3 14
+#define JMPTABL_SHIFT2 12
+#define JMPTABL_SHIFT1 12
+#define JMPTABL_SHIFT0 10
+#define JMPTABL_START4 (JMPTABL_START3+JMPTABL_SHIFT3)
+#define JMPTABL_START3 (JMPTABL_START2+JMPTABL_SHIFT2)
+#define JMPTABL_START2 (JMPTABL_START1+JMPTABL_SHIFT1)
+#define JMPTABL_START1 (JMPTABL_START0+JMPTABL_SHIFT0)
+#define JMPTABL_START0 0
+#define JMPTABLE_MASK4 ((1<<JMPTABL_SHIFT4)-1)
+#define JMPTABLE_MASK3 ((1<<JMPTABL_SHIFT3)-1)
+#define JMPTABLE_MASK2 ((1<<JMPTABL_SHIFT2)-1)
+#define JMPTABLE_MASK1 ((1<<JMPTABL_SHIFT1)-1)
+#define JMPTABLE_MASK0 ((1<<JMPTABL_SHIFT0)-1)
+#else
#define JMPTABL_SHIFT3 18
#define JMPTABL_SHIFT2 18
#define JMPTABL_SHIFT1 18
@@ -48,18 +65,20 @@ uintptr_t getJumpAddress64(uintptr_t addr);
#define JMPTABLE_MASK2 ((1<<JMPTABL_SHIFT2)-1)
#define JMPTABLE_MASK1 ((1<<JMPTABL_SHIFT1)-1)
#define JMPTABLE_MASK0 ((1<<JMPTABL_SHIFT0)-1)
+#endif //SAVE_MEM
#endif
#define PROT_DYNAREC 0x80
#define PROT_DYNAREC_R 0x40
#define PROT_NOPROT 0x20
-#define PROT_MMAP 0x10
#define PROT_DYN (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT)
-#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R | PROT_MMAP | PROT_NOPROT)
+#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT)
+#define PROT_WAIT 0xFF
void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
void setProtection_mmap(uintptr_t addr, size_t size, uint32_t prot);
+void setProtection_elf(uintptr_t addr, size_t size, uint32_t prot);
void freeProtection(uintptr_t addr, size_t size);
void refreshProtection(uintptr_t addr);
uint32_t getProtection(uintptr_t addr);
@@ -74,9 +93,11 @@ int AreaInHotPage(uintptr_t start, uintptr_t end);
void AddHotPage(uintptr_t addr);
#endif
void* find32bitBlock(size_t size);
-void* find31bitBlockNearHint(void* hint, size_t size);
+void* find31bitBlockNearHint(void* hint, size_t size, uintptr_t mask);
void* find47bitBlock(size_t size);
-void* find47bitBlockNearHint(void* hint, size_t size);
+void* find47bitBlockNearHint(void* hint, size_t size, uintptr_t mask); // mask can be 0 for default one (0xffff)
+void* find47bitBlockElf(size_t size, int mainbin, uintptr_t mask);
+int isBlockFree(void* hint, size_t size);
// unlock mutex that are locked by current thread (for signal handling). Return a mask of unlock mutex
int unlockCustommemMutex(void);
diff --git a/src/include/debug.h b/src/include/debug.h
index 8397d6c..948b29e 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -9,6 +9,7 @@ extern int box64_dynarec_log;
extern int box64_dynarec;
extern uintptr_t box64_pagesize;
extern uintptr_t box64_load_addr;
+extern int box64_dynarec_test;
#ifdef DYNAREC
extern int box64_dynarec_dump;
extern int box64_dynarec_trace;
@@ -24,25 +25,40 @@ extern int box64_dynarec_safeflags;
extern int box64_dynarec_callret;
extern int box64_dynarec_bleeding_edge;
extern int box64_dynarec_jvm;
+extern int box64_dynarec_tbb;
extern int box64_dynarec_hotpage;
extern int box64_dynarec_fastpage;
extern int box64_dynarec_wait;
-extern int box64_dynarec_test;
extern int box64_dynarec_missing;
+extern int box64_dynarec_aligned_atomics;
#ifdef ARM64
extern int arm64_asimd;
extern int arm64_aes;
extern int arm64_pmull;
extern int arm64_crc32;
extern int arm64_atomics;
+extern int arm64_sha1;
+extern int arm64_sha2;
+extern int arm64_flagm;
+extern int arm64_flagm2;
#elif defined(RV64)
extern int rv64_zba;
extern int rv64_zbb;
extern int rv64_zbc;
extern int rv64_zbs;
+extern int rv64_xtheadba;
+extern int rv64_xtheadbb;
+extern int rv64_xtheadbs;
+extern int rv64_xtheadcondmov;
+extern int rv64_xtheadmemidx;
+extern int rv64_xtheadmempair;
+extern int rv64_xtheadfmemidx;
+extern int rv64_xtheadmac;
+extern int rv64_xtheadfmv;
#endif
#endif
extern int box64_libcef;
+extern int box64_sdl2_jguid;
extern int dlsym_error; // log dlsym error
extern int cycle_log; // if using rolling logs
#ifdef HAVE_TRACE
@@ -56,10 +72,12 @@ extern char* box64_trace;
extern uint64_t start_cnt;
#endif
extern int box64_nosandbox;
+extern int box64_inprocessgpu;
extern int box64_malloc_hack;
extern int box64_dummy_crashhandler;
extern int box64_sse_flushto0;
extern int box64_x87_no80bits;
+extern int box64_sync_rounding;
extern int allow_missing_libs;
extern int box64_mapclean;
extern int box64_prefer_wrapped;
@@ -73,6 +91,7 @@ extern int box64_novulkan; // disabling the use of wrapped vulkan
extern int box64_showsegv; // show sigv, even if a signal handler is present
extern int box64_showbt; // show a backtrace if a signal is caught
extern int box64_isglibc234; // is the program linked with glibc 2.34+
+extern int box64_futex_waitv;
extern int box64_x11threads;
extern int box64_x11glx;
extern char* box64_libGL;
@@ -100,30 +119,32 @@ void printf_ftrace(const char* fmt, ...);
#ifdef BUILD_DYNAMIC
#define EXPORTDYN __attribute__((visibility("default")))
#else
-#define EXPORTDYN
+#define EXPORTDYN
#endif
void init_malloc_hook(void);
-extern size_t(*box_malloc_usable_size)(void*);
#ifdef ANDROID
-extern void*(*__libc_malloc)(size_t);
-extern void*(*__libc_realloc)(void*, size_t);
-extern void*(*__libc_calloc)(size_t, size_t);
-extern void (*__libc_free)(void*);
-extern void*(*__libc_memalign)(size_t, size_t);
+#define box_malloc malloc
+#define box_realloc realloc
+#define box_calloc calloc
+#define box_free free
+#define box_memalign memalign
+#define box_strdup strdup
+#define box_realpath realpath
#else
+extern size_t(*box_malloc_usable_size)(void*);
extern void* __libc_malloc(size_t);
extern void* __libc_realloc(void*, size_t);
extern void* __libc_calloc(size_t, size_t);
extern void __libc_free(void*);
extern void* __libc_memalign(size_t, size_t);
-#endif
#define box_malloc __libc_malloc
#define box_realloc __libc_realloc
#define box_calloc __libc_calloc
#define box_free __libc_free
-#define box_memalign __libc_memalign
+#define box_memalign __libc_memalign
extern char* box_strdup(const char* s);
extern char* box_realpath(const char* path, char* ret);
+#endif
#endif //__DEBUG_H_
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index ca8839d..bc09ad3 100644
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -14,6 +14,7 @@ typedef struct kh_defaultversion_s kh_defaultversion_t;
typedef struct dynablock_s dynablock_t;
#endif
+// Open an elfheader. Transfert control of f to elfheader also!
elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec); // exec : 0 = lib, 1 = exec
void FreeElfHeader(elfheader_t** head);
const char* ElfName(elfheader_t* head);
@@ -22,11 +23,9 @@ void ElfAttachLib(elfheader_t* head, library_t* lib);
// return 0 if OK
int CalcLoadAddr(elfheader_t* head);
-int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin);
+int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin);
void FreeElfMemory(elfheader_t* head);
-int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head);
int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded);
-int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head);
int RelocateElf(lib_t *maplib, lib_t* local_maplib, int bindnow, elfheader_t* head);
int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, int bindnow, elfheader_t* head);
void CalcStack(elfheader_t* h, uint64_t* stacksz, size_t* stackalign);
@@ -67,6 +66,7 @@ int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, const
int GetVersionIndice(elfheader_t* h, const char* vername);
int GetNeededVersionCnt(elfheader_t* h, const char* libname);
const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx);
+int GetNeededVersionForLib(elfheader_t* h, const char* libname, const char* ver);
kh_mapsymbols_t* GetMapSymbols(elfheader_t* h);
kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h);
diff --git a/src/include/gtkclass.h b/src/include/gtkclass.h
index 8a88a0d..2252c94 100644
--- a/src/include/gtkclass.h
+++ b/src/include/gtkclass.h
@@ -22,6 +22,17 @@ typedef struct my_GValue_s
} data[2];
} my_GValue_t;
+typedef struct my_GTypeInstance_s
+{
+ void* g_class;
+} my_GTypeInstance_t;
+
+typedef struct my_GObject_s
+{
+ my_GTypeInstance_t g_type_instance;
+ uint32_t ref_count;
+ void* qdata;
+} my_GObject_t;
typedef struct my_GObjectClass_s
{
@@ -39,6 +50,13 @@ typedef struct my_GObjectClass_s
void* pdummy[6];
} my_GObjectClass_t;
+typedef struct my_GInitiallyUnowned_s
+{
+ my_GTypeInstance_t g_type_instance;
+ uint32_t ref_count;
+ void* qdata;
+} my_GInitiallyUnowned_t;
+
typedef struct my_GInitiallyUnownedClass_s
{
int g_type_class;
@@ -55,15 +73,15 @@ typedef struct my_GInitiallyUnownedClass_s
void* pdummy[6];
} my_GInitiallyUnownedClass_t;
-typedef struct my_GamesScoresImporterClass_s
+typedef struct my_GApplication_s
{
- my_GObjectClass_t parent_class;
- void (*importOldScores) (void *self, void* context, void* new_scores_dir, void *error);
-}my_GamesScoresImporterClass_t;
+ my_GObject_t parent;
+ void* priv;
+} my_GApplication_t;
typedef struct my_GApplicationClass_s
{
- void* construct_properties;
+ my_GObjectClass_t parent_class;
void (* startup) (void* application);
void (* activate) (void* application);
void (* open) (void* application, void* files, int n_files, void* hint);
@@ -79,10 +97,15 @@ typedef struct my_GApplicationClass_s
void (* dbus_unregister) (void* appvoidlication, void* connection, void* object_path);
int (* handle_local_options) (void* application, void* options);
int (* name_lost) (void* application);
- uint32_t flags;
- void* pdummy[6];
+ void* padding[7];
} my_GApplicationClass_t;
+typedef struct my_GtkApplication_s
+{
+ my_GApplication_t parent;
+ void* priv;
+} my_GtkApplication_t;
+
typedef struct my_GtkApplicationClass_s
{
my_GApplicationClass_t parent_class;
@@ -90,14 +113,47 @@ typedef struct my_GtkApplicationClass_s
void (*window_removed) (void* application, void* window);
} my_GtkApplicationClass_t;
+typedef struct my_GtkObject_s
+{
+ my_GInitiallyUnowned_t parent;
+ uint32_t flags;
+} my_GtkObject_t;
+
typedef struct my_GtkObjectClass_s
{
- my_GObjectClass_t parent_class;
+ my_GInitiallyUnownedClass_t parent_class;
void (*set_arg) (void* object, void* arg, uint32_t arg_id);
void (*get_arg) (void* object, void* arg, uint32_t arg_id);
void (*destroy) (void* object);
} my_GtkObjectClass_t;
+typedef struct my_GdkRectangle_s
+{
+ int x;
+ int y;
+ int width;
+ int height;
+} my_GdkRectangle_t;
+
+typedef struct my_GtkRequisition_s
+{
+ int width;
+ int height;
+} my_GtkRequisition_t;
+
+typedef struct my_GtkWidget2_s
+{
+ my_GtkObject_t private;
+ int16_t private_flags;
+ uint8_t state;
+ char* name;
+ void* style; //GtkStyle
+ my_GtkRequisition_t requisition;
+ my_GdkRectangle_t allocation;
+ void* window; //GdkWindow
+ void* parent; //GtkWidget
+} my_GtkWidget2_t;
+
typedef struct my_GtkWidget2Class_s
{
my_GtkObjectClass_t parent_class;
@@ -174,6 +230,12 @@ typedef struct my_GtkWidget2Class_s
void (*_gtk_reserved7) (void);
} my_GtkWidget2Class_t;
+typedef struct my_GtkWidget3_s
+{
+ my_GInitiallyUnowned_t parent;
+ void* priv;
+} my_GtkWidget3_t;
+
typedef struct my_GtkWidget3Class_s
{
my_GInitiallyUnownedClass_t parent_class;
@@ -265,6 +327,17 @@ typedef struct my_GtkWidget3Class_s
void (*_gtk_reserved7) (void);
} my_GtkWidget3Class_t;
+typedef struct my_GtkContainer2_s
+{
+ my_GtkWidget2_t parent;
+ void* focus_child; //GtkWidget
+ uint32_t border_width : 16;
+ uint32_t need_resize : 1;
+ uint32_t resize_mode : 2;
+ uint32_t reallocate_redraws : 1;
+ uint32_t has_focus_chain : 1;
+} my_GtkContainer2_t;
+
typedef struct my_GtkContainer2Class_s
{
my_GtkWidget2Class_t parent_class;
@@ -283,6 +356,12 @@ typedef struct my_GtkContainer2Class_s
void (*_gtk_reserved4) (void);
} my_GtkContainer2Class_t;
+typedef struct my_GtkContainer3_s
+{
+ my_GtkWidget3_t parent;
+ void* priv;
+} my_GtkContainer3_t;
+
typedef struct my_GtkContainer3Class_s
{
my_GtkWidget3Class_t parent_class;
@@ -307,6 +386,12 @@ typedef struct my_GtkContainer3Class_s
void (*_gtk_reserved8) (void);
} my_GtkContainer3Class_t;
+typedef struct my_GtkAction_s
+{
+ my_GObject_t parent;
+ void* private_data;
+} my_GtkAction_t;
+
typedef struct my_GtkActionClass_s
{
my_GObjectClass_t parent_class;
@@ -324,11 +409,26 @@ typedef struct my_GtkActionClass_s
void (*_gtk_reserved4) (void);
} my_GtkActionClass_t;
+typedef struct my_GtkMisc2_s
+{
+ my_GtkWidget2_t parent;
+ float xalign;
+ float yalign;
+ uint16_t xpad;
+ uint16_t ypad;
+} my_GtkMisc2_t;
+
typedef struct my_GtkMisc2Class_s
{
my_GtkWidget2Class_t parent_class;
} my_GtkMisc2Class_t;
+typedef struct my_GtkMisc3_s
+{
+ my_GtkWidget3_t parent;
+ void* priv;
+} my_GtkMisc3_t;
+
typedef struct my_GtkMisc3Class_s
{
my_GtkWidget3Class_t parent_class;
@@ -338,11 +438,45 @@ typedef struct my_GtkMisc3Class_s
void (*_gtk_reserved4) (void);
} my_GtkMisc3Class_t;
-typedef struct my_GtkMenuButtonClass_s
+typedef struct my_GtkImage3_s
{
- my_GtkWidget3Class_t parent_class;
- void (* activate) (void *self);
-}my_GtkMenuButtonClass_t;
+ my_GtkMisc3_t parent;
+ void* priv;
+} my_GtkImage3_t;
+
+typedef struct my_GtkImageClass_s
+{
+ my_GtkMisc3Class_t parent_class;
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+} my_GtkImage3Class_t;
+
+typedef struct my_GtkLabel2_s
+{
+ my_GtkMisc2_t misc;
+ char* label;
+ uint32_t jtype : 2;
+ uint32_t wrap : 1;
+ uint32_t use_underline : 1;
+ uint32_t use_markup : 1;
+ uint32_t ellipsize : 3;
+ uint32_t single_line_mode : 1;
+ uint32_t have_transform : 1;
+ uint32_t in_click : 1;
+ uint32_t wrap_mode : 3;
+ uint32_t pattern_set : 1;
+ uint32_t track_links : 1;
+ uint32_t mnemonic_keyval;
+ char* text;
+ void* attrs; //PangoAttrList
+ void* effective_attrs; //PangoAttrList
+ void* layout; //PangoLayout
+ void* mnemonic_widget; //GtkWidget
+ void* mnemonic_window; //GtkWindow
+ void* select_info; //GtkLabelSelectionInfo
+} my_GtkLabel2_t;
typedef struct my_GtkLabel2Class_s
{
@@ -356,6 +490,12 @@ typedef struct my_GtkLabel2Class_s
void (*_gtk_reserved3) (void);
} my_GtkLabel2Class_t;
+typedef struct my_GtkLabel3_s
+{
+ my_GtkMisc3_t misc;
+ void* priv;
+} my_GtkLabel3_t;
+
typedef struct my_GtkLabel3Class_s
{
my_GtkMisc3Class_t parent_class;
@@ -373,6 +513,12 @@ typedef struct my_GtkLabel3Class_s
void (*_gtk_reserved8) (void);
} my_GtkLabel3Class_t;
+typedef struct my_GtkTreeView2_s
+{
+ my_GtkContainer2_t parent;
+ void* priv;
+} my_GtkTreeView2_t;
+
typedef struct my_GtkTreeView2Class_s
{
my_GtkContainer2Class_t parent_class;
@@ -399,6 +545,12 @@ typedef struct my_GtkTreeView2Class_s
void (*_gtk_reserved4) (void);
} my_GtkTreeView2Class_t;
+typedef struct my_GtkBin2_s
+{
+ my_GtkContainer2_t container;
+ void* child; //GtkWidget
+} my_GtkBin2_t;
+
typedef struct my_GtkBin2Class_s
{
my_GtkContainer2Class_t parent_class;
@@ -408,6 +560,12 @@ typedef struct my_GtkBin2Class_s
void (*_gtk_reserved4) (void);
} my_GtkBin2Class_t;
+typedef struct my_GtkBin3_s
+{
+ my_GtkContainer3_t container;
+ void* priv;
+} my_GtkBin3_t;
+
typedef struct my_GtkBin3Class_s
{
my_GtkContainer3Class_t parent_class;
@@ -417,6 +575,49 @@ typedef struct my_GtkBin3Class_s
void (*_gtk_reserved4) (void);
} my_GtkBin3Class_t;
+typedef struct my_GtkWindow2_s
+{
+ my_GtkBin2_t parent;
+ char* title;
+ char* wmclass_name;
+ char* wmclass_class;
+ char* wm_role;
+ void* focus_widget; // GtkWidget
+ void* default_widget; // GtkWidget
+ void* transient_parent; // GtkWindow
+ void* geometry_info; // GtkWindowGeometryInfo
+ void* frame; // GdkWindow
+ void* group; // GtkWindowGroup
+ uint16_t configure_request_count;
+ uint32_t allow_shrink : 1;
+ uint32_t allow_grow : 1;
+ uint32_t configure_notify_received : 1;
+ uint32_t need_default_position : 1;
+ uint32_t need_default_size : 1;
+ uint32_t position : 3;
+ uint32_t type : 4;
+ uint32_t has_user_ref_count : 1;
+ uint32_t has_focus : 1;
+ uint32_t modal : 1;
+ uint32_t destroy_with_parent : 1;
+ uint32_t has_frame : 1;
+ uint32_t iconify_initially : 1;
+ uint32_t stick_initially : 1;
+ uint32_t maximize_initially : 1;
+ uint32_t decorated : 1;
+ uint32_t type_hint : 3;
+ uint32_t gravity : 5;
+ uint32_t is_active : 1;
+ uint32_t has_toplevel_focus : 1;
+ uint32_t frame_left;
+ uint32_t frame_top;
+ uint32_t frame_right;
+ uint32_t frame_bottom;
+ uint32_t keys_changed_handler;
+ int mnemonic_modifier;
+ void* screen; // GdkScreen
+} my_GtkWindow2_t;
+
typedef struct my_GtkWindow2Class_s {
my_GtkBin2Class_t parent_class;
void (* set_focus) (void* window, void* focus);
@@ -431,6 +632,12 @@ typedef struct my_GtkWindow2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkWindow2Class_t;
+typedef struct my_GtkWindow3_s
+{
+ my_GtkBin3_t bin;
+ void* priv;
+} my_GtkWindow3_t;
+
typedef struct my_GtkWindow3Class_s
{
my_GtkBin3Class_t parent_class;
@@ -444,11 +651,22 @@ typedef struct my_GtkWindow3Class_s
void (* _gtk_reserved3) (void);
}my_GtkWindow3Class_t;
+typedef struct my_GtkApplicationWindow_s
+{
+ my_GtkWindow3_t parent;
+ void* priv;
+} my_GtkApplicationWindow_t;
+
typedef struct my_GtkApplicationWindowClass_s
{
my_GtkWindow3Class_t parent_class;
}my_GtkApplicationWindowClass_t;
+typedef struct my_GtkListBox_s
+{
+ my_GtkContainer3_t parent;
+} my_GtkListBox_t;
+
typedef struct my_GtkListBoxClass_s
{
my_GtkContainer3Class_t parent_class;
@@ -465,6 +683,11 @@ typedef struct my_GtkListBoxClass_s
void (* _gtk_reserved3) (void);
}my_GtkListBoxClass_t;
+typedef struct my_GtkListBoxRow_s
+{
+ my_GtkBin3_t parent;
+} my_GtkListBoxRow_t;
+
typedef struct my_GtkListBoxRowClass_s {
my_GtkBin3Class_t parent_class;
void (* activate) (void* row);
@@ -472,6 +695,23 @@ typedef struct my_GtkListBoxRowClass_s {
void (* _gtk_reserved2) (void);
}my_GtkListBoxRowClass_t;
+typedef struct my_GtkButton2_s
+{
+ my_GtkBin2_t bin;
+ void* event_window; // GdkWindow
+ char* label_text;
+ uint32_t activate_timeout;
+ uint32_t constructed : 1;
+ uint32_t in_button : 1;
+ uint32_t button_down : 1;
+ uint32_t relief : 2;
+ uint32_t use_underline : 1;
+ uint32_t use_stock : 1;
+ uint32_t depressed : 1;
+ uint32_t depress_on_activate : 1;
+ uint32_t focus_on_click : 1;
+} my_GtkButton2_t;
+
typedef struct my_GtkButton2Class_s {
my_GtkBin2Class_t parent_class;
void (* pressed) (void *button);
@@ -486,6 +726,12 @@ typedef struct my_GtkButton2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkButton2Class_t;
+typedef struct my_GtkButton3_s
+{
+ my_GtkBin3_t bin;
+ void* priv;
+} my_GtkButton3_t;
+
typedef struct my_GtkButton3Class_s {
my_GtkBin3Class_t parent_class;
void (* pressed) (void *button);
@@ -500,6 +746,14 @@ typedef struct my_GtkButton3Class_s {
void (*_gtk_reserved4) (void);
} my_GtkButton3Class_t;
+typedef struct my_GtkToggleButton2_s
+{
+ my_GtkButton2_t button;
+ uint32_t active : 1;
+ uint32_t draw_indicator : 1;
+ uint32_t inconsistent : 1;
+} my_GtkToggleButton2_t;
+
typedef struct my_GtkToggleButton2Class_s {
my_GtkButton2Class_t parent_class;
void (* toggled) (void* toggle_button);
@@ -509,6 +763,27 @@ typedef struct my_GtkToggleButton2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkToggleButton2Class_t;
+typedef struct my_GtkToggleButton3_s
+{
+ my_GtkButton3_t parent;
+ void* priv;
+} my_GtkToggleButton3_t;
+
+typedef struct my_GtkToggleButton3Class_s
+{
+ my_GtkButton3Class_t parent_class;
+ void (* toggled) (void* toggle_button);
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+} my_GtkToggleButton3Class_t;
+
+typedef struct my_GtkCheckButton2_s
+{
+ my_GtkToggleButton2_t parent;
+} my_GtkCheckButton2_t;
+
typedef struct my_GtkCheckButton2Class_s {
my_GtkToggleButton2Class_t parent_class;
void (* draw_indicator) (void* check_button, void* area);
@@ -517,6 +792,40 @@ typedef struct my_GtkCheckButton2Class_s {
void (*_gtk_reserved2) (void);
} my_GtkCheckButton2Class_t;
+typedef struct my_GtkCheckButton3_s
+{
+ my_GtkToggleButton3_t parent;
+} my_GtkCheckButton3_t;
+
+typedef struct my_GtkCheckButton3Class_s {
+ my_GtkToggleButton3Class_t parent_class;
+ void (* draw_indicator) (void* check_button, void* area);
+ void (*_gtk_reserved0) (void);
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+} my_GtkCheckButton3Class_t;
+
+typedef struct my_GtkMenuButton3_s
+{
+ my_GtkToggleButton3_t parent;
+ void* priv;
+} my_GtkMenuButton3_t;
+
+typedef struct my_GtkMenuButton3Class_s
+{
+ my_GtkToggleButton3Class_t parent_class;
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+}my_GtkMenuButton3Class_t;
+
+typedef struct my_GtkComboBox2_s
+{
+ my_GtkBin2_t parent;
+ void* priv;
+} my_GtkComboBox2_t;
+
typedef struct my_GtkComboBox2Class_s {
my_GtkBin2Class_t parent_class;
void (* changed) (void* combo_box);
@@ -527,6 +836,52 @@ typedef struct my_GtkComboBox2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkComboBox2Class_t;
+typedef struct my_GtkEntry2_s
+{
+ my_GtkWidget2_t parent;
+ char* text;
+ uint32_t editable : 1;
+ uint32_t visible : 1;
+ uint32_t overwrite_mode : 1;
+ uint32_t in_drag : 1;
+ uint16_t text_length;
+ uint16_t text_max_length;
+ void* text_area; // GdkWindow
+ void* im_context; // GtkIMContext
+ void* popup_menu; // GtkWidget
+ int current_pos;
+ int selection_bound;
+ void* cached_layout; // PangoLayout
+ uint32_t cache_includes_preedit : 1;
+ uint32_t need_im_reset : 1;
+ uint32_t has_frame : 1;
+ uint32_t activates_default : 1;
+ uint32_t cursor_visible : 1;
+ uint32_t in_click : 1;
+ uint32_t is_cell_renderer : 1;
+ uint32_t editing_canceled : 1;
+ uint32_t mouse_cursor_obscured : 1;
+ uint32_t select_words : 1;
+ uint32_t select_lines : 1;
+ uint32_t resolved_dir : 4;
+ uint32_t truncate_multiline : 1;
+ uint32_t button;
+ uint32_t blink_timeout;
+ uint32_t recompute_idle;
+ int scroll_offset;
+ int ascent;
+ int descent;
+ uint16_t x_text_size;
+ uint16_t x_n_bytes;
+ uint16_t preedit_length;
+ uint16_t preedit_cursor;
+ int dnd_position;
+ int drag_start_x;
+ int drag_start_y;
+ uint32_t invisible_char;
+ int width_chars;
+} my_GtkEntry2_t;
+
typedef struct my_GtkEntry2Class_s {
my_GtkWidget2Class_t parent_class;
void (* populate_popup) (void* entry, void* menu);
@@ -544,6 +899,26 @@ typedef struct my_GtkEntry2Class_s {
void (*_gtk_reserved2) (void);
} my_GtkEntry2Class_t;
+typedef struct my_GtkSpinButton2_s
+{
+ my_GtkEntry2_t entry;
+ void* adjustment; // GtkAdjustment
+ void* panel; // GdkWindow
+ uint32_t timer;
+ double climb_rate;
+ double timer_step;
+ int update_policy;
+ uint32_t in_child : 2;
+ uint32_t click_child : 2;
+ uint32_t button : 2;
+ uint32_t need_timer : 1;
+ uint32_t timer_calls : 3;
+ uint32_t digits : 10;
+ uint32_t numeric : 1;
+ uint32_t wrap : 1;
+ uint32_t snap_to_ticks : 1;
+} my_GtkSpinButton2_t;
+
typedef struct my_GtkSpinButton2Class_s {
my_GtkEntry2Class_t parent_class;
int (*input) (void* spin_button, void* new_value);
@@ -556,8 +931,21 @@ typedef struct my_GtkSpinButton2Class_s {
void (*_gtk_reserved3) (void);
} my_GtkSpinButton2Class_t;
+typedef struct my_GtkProgress2_s
+{
+ my_GtkWidget2_t widget;
+ void* adjustment; // GtkAdjustment
+ void* offscreen_pixmap; // GdkPixmap
+ char* format;
+ float x_align;
+ float y_align;
+ uint32_t show_text : 1;
+ uint32_t activity_mode : 1;
+ uint32_t use_text_format : 1;
+} my_GtkProgress2_t;
+
typedef struct my_GtkProgress2Class_s {
- my_GtkWidget2Class_t parent_class;
+ my_GtkWidget2Class_t parent;
void (* paint) (void* progress);
void (* update) (void* progress);
void (* act_mode_enter) (void* progress);
@@ -567,6 +955,22 @@ typedef struct my_GtkProgress2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkProgress2Class_t;
+typedef struct my_GtkProgressBar2_s
+{
+ my_GtkProgress2_t parent;
+ int bar_style;
+ int orientation;
+ uint32_t blocks;
+ int in_block;
+ int activity_pos;
+ uint32_t activity_step;
+ uint32_t activity_blocks;
+ double pulse_fraction;
+ uint32_t activity_dir : 1;
+ uint32_t ellipsize : 3;
+ uint32_t dirty : 1;
+} my_GtkProgressBar2_t;
+
typedef struct my_GtkProgressBar2Class_s {
my_GtkProgress2Class_t parent_class;
void (*_gtk_reserved1) (void);
@@ -575,11 +979,38 @@ typedef struct my_GtkProgressBar2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkProgressBar2Class_t;
+typedef struct my_GtkFrame2_s
+{
+ my_GtkBin2_t bin;
+ void* label_widget; // GtkWidget
+ int16_t shadow_type;
+ float label_xalign;
+ float label_yalign;
+ my_GdkRectangle_t child_allocation;
+} my_GtkFrame2_t;
+
typedef struct my_GtkFrame2Class_s {
my_GtkBin2Class_t parent_class;
void (*compute_child_allocation) (void* frame, void* allocation);
} my_GtkFrame2Class_t;
+typedef struct my_GtkMenuShell2_s
+{
+ my_GtkContainer2_t container;
+ void* children; // GList
+ void* active_menu_item; // GtkWidget
+ void* parent_menu_shell; // GtkWidget
+ uint32_t button;
+ uint32_t activate_time;
+ uint32_t active : 1;
+ uint32_t have_grab : 1;
+ uint32_t have_xgrab : 1;
+ uint32_t ignore_leave : 1;
+ uint32_t menu_flag : 1;
+ uint32_t ignore_enter : 1;
+ uint32_t keyboard_mode : 1;
+} my_GtkMenuShell2_t;
+
typedef struct my_GtkMenuShell2Class_s {
my_GtkContainer2Class_t parent_class;
void (*deactivate) (void* menu_shell);
@@ -595,6 +1026,11 @@ typedef struct my_GtkMenuShell2Class_s {
void (*_gtk_reserved2) (void);
} my_GtkMenuShell2Class_t;
+typedef struct my_GtkMenuBar2_s
+{
+ my_GtkMenuShell2_t parent;
+} my_GtkMenuBar2_t;
+
typedef struct my_GtkMenuBar2Class_s {
my_GtkMenuShell2Class_t parent_class;
void (*_gtk_reserved1) (void);
@@ -603,6 +1039,58 @@ typedef struct my_GtkMenuBar2Class_s {
void (*_gtk_reserved4) (void);
} my_GtkMenuBar2Class_t;
+typedef struct my_GtkTextView2_s
+{
+ my_GtkContainer2_t parent;
+ void* layout; // struct _GtkTextLayout
+ void* buffer; // GtkTextBuffer
+ uint32_t selection_drag_handler;
+ uint32_t scroll_timeout;
+ int pixels_above_lines;
+ int pixels_below_lines;
+ int pixels_inside_wrap;
+ int wrap_mode;
+ int justify;
+ int left_margin;
+ int right_margin;
+ int indent;
+ void* tabs; // PangoTabArray
+ uint32_t editable : 1;
+ uint32_t overwrite_mode : 1;
+ uint32_t cursor_visible : 1;
+ uint32_t need_im_reset : 1;
+ uint32_t accepts_tab : 1;
+ uint32_t width_changed : 1;
+ uint32_t onscreen_validated : 1;
+ uint32_t mouse_cursor_obscured : 1;
+ void* text_window; // GtkTextWindow
+ void* left_window; // GtkTextWindow
+ void* right_window; // GtkTextWindow
+ void* top_window; // GtkTextWindow
+ void* bottom_window; // GtkTextWindow
+ void* hadjustment; // GtkAdjustment
+ void* vadjustment; // GtkAdjustment
+ int xoffset;
+ int yoffset;
+ int width;
+ int height;
+ int virtual_cursor_x;
+ int virtual_cursor_y;
+ void* first_para_mark; // GtkTextMark
+ int first_para_pixels;
+ void* dnd_mark; // GtkTextMark
+ uint32_t blink_timeout;
+ uint32_t first_validate_idle;
+ uint32_t incremental_validate_idle;
+ void* im_context; // GtkIMContext
+ void* popup_menu; // GtkWidget
+ int drag_start_x;
+ int drag_start_y;
+ void* children; // GSList
+ void* pending_scroll; // GtkTextPendingScroll
+ int pending_place_cursor_button;
+} my_GtkTextView2_t;
+
typedef struct my_GtkTextView2Class_s {
my_GtkContainer2Class_t parent_class;
void (* set_scroll_adjustments) (void* text_view, void* hadjustment, void* vadjustment);
@@ -627,6 +1115,12 @@ typedef struct my_GtkTextView2Class_s {
void (*_gtk_reserved7) (void);
} my_GtkTextView2Class_t;
+typedef struct my_GtkTextView3_s
+{
+ my_GtkContainer3_t parent;
+ void* priv;
+} my_GtkTextView3_t;
+
typedef struct my_GtkTextView3Class_s {
my_GtkContainer3Class_t parent_class;
void (* populate_popup) (void* text_view, void* menu);
@@ -649,6 +1143,12 @@ typedef struct my_GtkTextView3Class_s {
void (*_gtk_reserved4) (void);
} my_GtkTextView3Class_t;
+typedef struct my_GtkGrid3_s
+{
+ my_GtkContainer3_t parent;
+ void* priv;
+} my_GtkGrid3_t;
+
typedef struct my_GtkGrid3Class_s {
my_GtkContainer3Class_t parent_class;
void (* _gtk_reserved1) (void);
@@ -661,6 +1161,11 @@ typedef struct my_GtkGrid3Class_s {
void (* _gtk_reserved8) (void);
}my_GtkGrid3Class_t;
+typedef struct my_GtkEventController_s
+{
+ my_GObject_t parent;
+} my_GtkEventController_t;
+
typedef struct my_GtkEventControllerClass_s {
my_GObjectClass_t parent_class;
void (* set_widget) (void *controller, void *widget);
@@ -672,6 +1177,11 @@ typedef struct my_GtkEventControllerClass_s {
void* padding[10];
}my_GtkEventControllerClass_t;
+typedef struct my_GtkGesture_s
+{
+ my_GtkEventController_t parent;
+} my_GtkGesture_t;
+
typedef struct my_GtkGestureClass_s {
my_GtkEventControllerClass_t parent_class;
int (* check) (void *gesture);
@@ -683,11 +1193,21 @@ typedef struct my_GtkGestureClass_s {
void* padding[10];
}my_GtkGestureClass_t;
+typedef struct my_GtkGestureSingle_s
+{
+ my_GtkGesture_t parent;
+} my_GtkGestureSingle_t;
+
typedef struct my_GtkGestureSingleClass_s {
my_GtkGestureClass_t parent_class;
void* padding[10];
}my_GtkGestureSingleClass_t;
+typedef struct my_GtkGestureLongPress_s
+{
+ my_GtkGestureSingle_t parent;
+} my_GtkGestureLongPress_t;
+
typedef struct my_GtkGestureLongPressClass_s {
my_GtkGestureSingleClass_t parent_class;
void (* pressed) (void *gesture, double x, double y);
@@ -696,22 +1216,63 @@ typedef struct my_GtkGestureLongPressClass_s {
void* padding[10];
}my_GtkGestureLongPressClass_t;
+typedef struct my_MetaFrames2_s
+{
+ my_GtkWindow2_t parent; // to be checked (is MetaFrame2 still usefull?)
+} my_MetaFrames2_t;
+
typedef struct my_MetaFrames2Class_s
{
my_GtkWindow2Class_t parent_class;
} my_MetaFrames2Class_t;
+typedef struct my_GtkTable2_s
+{
+ my_GtkContainer2_t container;
+ void* children; // GList
+ void* rows; // GtkTableRowCol
+ void* cols; // GtkTableRowCol
+ uint16_t nrows;
+ uint16_t ncols;
+ uint16_t column_spacing;
+ uint16_t row_spacing;
+ uint32_t homogeneous : 1;
+} my_GtkTable2_t;
+
typedef struct my_GtkTable2Class_s
{
my_GtkContainer2Class_t parent_class;
} my_GtkTable2Class_t;
+typedef struct my_GtkFixed2_s
+{
+ my_GtkContainer2_t parent;
+ void* children; // GList
+} my_GtkFixed2_t;
+
typedef struct my_GtkFixed2Class_s
{
my_GtkContainer2Class_t parent_class;
} my_GtkFixed2Class_t;
+typedef struct my_GtkFixed3_s
+{
+ my_GtkContainer3_t parent;
+} my_GtkFixed3_t;
+
+typedef struct my_GtkFixed3Class_s
+{
+ my_GtkContainer3Class_t parent_class;
+ void* padding[8];
+} my_GtkFixed3Class_t;
+
+typedef struct my_GDBusObjectManagerClient_s
+{
+ my_GObject_t parent;
+ void* priv;
+} my_GDBusObjectManagerClient_t;
+
typedef struct my_GDBusObjectManagerClientClass_s
{
my_GObjectClass_t parent_class;
@@ -720,6 +1281,17 @@ typedef struct my_GDBusObjectManagerClientClass_s
void* padding[8];
} my_GDBusObjectManagerClientClass_t;
+typedef struct my_AtkObject_s
+{
+ my_GObject_t parent;
+ char* description;
+ char* name;
+ void* accessible_parent; // AtkObject
+ int role;
+ void* relation_set; // AtkRelationSet
+ int layer;
+} my_AtkObject_t;
+
typedef struct my_AtkObjectClass_s
{
my_GObjectClass_t parent;
@@ -752,6 +1324,11 @@ typedef struct my_AtkObjectClass_s
void* pad1;
} my_AtkObjectClass_t;
+typedef struct my_AtkUtil_s
+{
+ my_GObject_t parent;
+} my_AtkUtil_t;
+
typedef struct my_AtkUtilClass_s
{
my_GObjectClass_t parent;
@@ -764,6 +1341,25 @@ typedef struct my_AtkUtilClass_s
void* (* get_toolkit_version) (void);
} my_AtkUtilClass_t;
+typedef union my_GMutex_s
+{
+ void* p;
+ uint32_t i[2];
+} my_GMutex_t;
+
+typedef struct my_GstObject_s
+{
+ my_GInitiallyUnowned_t parent;
+ my_GMutex_t lock;
+ char* name;
+ void* _parent; // GstObject
+ uint32_t flags;
+ void* control_bindings; // GList
+ uint64_t control_rate;
+ uint64_t last_sync;
+ void* _gst_reserved;
+} my_GstObject_t;
+
typedef struct my_GstObjectClass_s {
my_GInitiallyUnownedClass_t parent;
const char* path_string_separator;
@@ -771,13 +1367,36 @@ typedef struct my_GstObjectClass_s {
void* _gst_reserved[4];
} my_GstObjectClass_t;
-typedef struct my_GstAllocatorClass_s {
+typedef struct my_GstAllocator_s
+{
+ my_GstObject_t parent;
+ const char* mem_type;
+ void*(*mem_map) (void* mem, size_t maxsize, int flags);
+ void (*mem_unmap) (void* mem);
+ void*(*mem_copy) (void* mem, ssize_t offset, ssize_t size);
+ void*(*mem_share) (void* mem, ssize_t offset, ssize_t size);
+ int (*mem_is_span) (void* mem1, void* mem2, void* offset);
+ void*(*mem_map_full) (void* mem, void* info, size_t maxsize);
+ void (*mem_unmap_full)(void* mem, void* info);
+ void* _gst_reserved[4 - 2];
+ void* priv;
+} my_GstAllocator_t;
+
+typedef struct my_GstAllocatorClass_s
+{
my_GstObjectClass_t parent;
void* (*alloc) (void *allocator, size_t size, void *params);
void (*free) (void *allocator, void *memory);
void* _gst_reserved[4];
} my_GstAllocatorClass_t;
+typedef struct my_GstTaskPool_s
+{
+ my_GstObject_t parent;
+ void* pool; // GThreadPool
+ void* _gst_reserved[4];
+} my_GstTaskPool_t;
+
typedef struct my_GstTaskPoolClass_s {
my_GstObjectClass_t parent_class;
void (*prepare) (void* pool, void* error);
@@ -788,6 +1407,686 @@ typedef struct my_GstTaskPoolClass_s {
void* _gst_reserved[4-1];
} my_GstTaskPoolClass_t;
+typedef struct my_GCond_s
+{
+ void* p;
+ uint32_t i[2];
+} my_GCond_t;
+
+typedef struct my_GRecMutex_s
+{
+ void* p;
+ uint32_t i[2];
+} my_GRecMutex_t;
+
+typedef struct my_GstElement_s
+{
+ my_GstObject_t parent;
+ my_GRecMutex_t state_lock;
+ my_GCond_t state_cond;
+ uint32_t state_cookie;
+ int target_state;
+ int current_state;
+ int next_state;
+ int pending_state;
+ int last_return;
+ void* bus; // GstBus
+ void* clock; // GstClock
+ int64_t base_time;
+ uint64_t start_time;
+ uint16_t numpads;
+ void* pads; //GstClock
+ uint16_t numsrcpads;
+ void* srcpads; //GstClock
+ uint16_t numsinkpads;
+ void* sinkpads; //GstClock
+ uint32_t pads_cookie;
+ void* contexts; //GstClock
+ void* _gst_reserved[4-1];
+} my_GstElement_t;
+
+typedef struct my_GstElementClass_s {
+ my_GstObjectClass_t parent_class;
+ void* metadata;
+ void* elementfactory;
+ void* padtemplates;
+ int numpadtemplates;
+ uint32_t pad_templ_cookie;
+ void (*pad_added) (void* element, void* pad);
+ void (*pad_removed) (void* element, void* pad);
+ void (*no_more_pads) (void* element);
+ void* (*request_new_pad) (void* element, void* templ, void* name, void* caps);
+ void (*release_pad) (void* element, void* pad);
+ int (*get_state) (void* element, void* state, void* pending, uint64_t timeout);
+ int (*set_state) (void* element, int state);
+ int (*change_state) (void* element, int transition);
+ void (*state_changed) (void* element, int oldstate, int newstate, int pending);
+ void (*set_bus) (void* element, void* bus);
+ void* (*provide_clock) (void* element);
+ int (*set_clock) (void* element, void* clock);
+ int (*send_event) (void* element, void* event);
+ int (*query) (void* element, void* query);
+ int (*post_message) (void* element, void* message);
+ void (*set_context) (void* element, void* context);
+ void* _gst_reserved[20-2];
+} my_GstElementClass_t;
+
+typedef struct my_GstBin_s {
+ my_GstElement_t parent;
+ int numchildren;
+ void* children; // GList
+ uint32_t children_cookie;
+ void* child_bus; // GstBus
+ void* messages; // GList
+ int polling;
+ int state_dirty;
+ int clock_dirty;
+ void* provided_clock; // GstClock
+ void* clock_provider; // GstElement
+ void* priv;
+ void* _gst_reserved[4];
+} my_GstBin_t;
+
+typedef struct my_GstBinClass_s {
+ my_GstElementClass_t parent_class;
+ void* pool;
+ void (*element_added) (void* bin, void* child);
+ void (*element_removed) (void* bin, void* child);
+ int (*add_element) (void* bin, void* element);
+ int (*remove_element) (void* bin, void* element);
+ void (*handle_message) (void* bin, void* message);
+ int (*do_latency) (void* bin);
+ void (*deep_element_added) (void* bin, void* sub_bin, void* child);
+ void (*deep_element_removed) (void* bin, void* sub_bin, void* child);
+ void* _gst_reserved[4-2];
+} my_GstBinClass_t;
+
+typedef struct my_GstSegment_s
+{
+ int flags;
+ double rate;
+ double applied_rate;
+ int format;
+ uint64_t base;
+ uint64_t offset;
+ uint64_t start;
+ uint64_t stop;
+ uint64_t time;
+ uint64_t position;
+ uint64_t duration;
+ void* _gst_reserved[4];
+} my_GstSegment_t;
+
+typedef struct my_GstBaseTransform_s
+{
+ my_GstElement_t parent;
+ void* sinkpad; // GstPad
+ void* srcpad; // GstPad
+ int have_segment;
+ my_GstSegment_t segment;
+ void* queued_buf; // GstBuffer
+ void* priv;
+ void* _gst_reserved[20-1];
+} my_GstBaseTransform_t;
+
+typedef struct my_GstBaseTransformClass_s {
+ my_GstElementClass_t parent_class;
+ int passthrough_on_same_caps;
+ int transform_ip_on_passthrough;
+ void* (*transform_caps) (void* trans, int direction, void* caps, void* filter);
+ void* (*fixate_caps) (void* trans, int direction, void* caps, void* othercaps);
+ int (*accept_caps) (void* trans, int direction, void* caps);
+ int (*set_caps) (void* trans, void* incaps, void* outcaps);
+ int (*query) (void* trans, int direction, void* query);
+ int (*decide_allocation) (void* trans, void* query);
+ int (*filter_meta) (void* trans, void* query, size_t api, void* params);
+ int (*propose_allocation) (void* trans, void* decide_query, void* query);
+ int (*transform_size) (void* trans, int direction, void* caps, size_t size, void* othercaps, void* othersize);
+ int (*get_unit_size) (void* trans, void* caps, void* size);
+ int (*start) (void* trans);
+ int (*stop) (void* trans);
+ int (*sink_event) (void* trans, void* event);
+ int (*src_event) (void* trans, void* event);
+ int (*prepare_output_buffer) (void* trans, void* input, void* outbuf);
+ int (*copy_metadata) (void* trans, void* input, void* outbuf);
+ int (*transform_meta) (void* trans, void* outbuf, void* meta, void* inbuf);
+ void (*before_transform) (void* trans, void* buffer);
+ int (*transform) (void* trans, void* inbuf, void* outbuf);
+ int (*transform_ip) (void* trans, void* buf);
+ int (*submit_input_buffer) (void* trans, int is_discont, void* input);
+ int (*generate_output) (void* trans, void* outbuf);
+ void* _gst_reserved[20-2];
+} my_GstBaseTransformClass_t;
+
+typedef struct my_GstVideoDecoder_s
+{
+ my_GstElement_t parent;
+ void* sinkpad; // GstPad
+ void* srcpad; // GstPad
+ my_GRecMutex_t stream_lock;
+ my_GstSegment_t input_segment;
+ my_GstSegment_t output_segment;
+ void* priv;
+ void* padding[20];
+} my_GstVideoDecoder_t;
+
+typedef struct my_GstVideoDecoderClass_s {
+ my_GstElementClass_t parent_class;
+ int (*open) (void* decoder);
+ int (*close) (void* decoder);
+ int (*start) (void* decoder);
+ int (*stop) (void* decoder);
+ int (*parse) (void* decoder, void* frame, void* adapter, int at_eos);
+ int (*set_format) (void* decoder, void* state);
+ int (*reset) (void* decoder, int hard);
+ int (*finish) (void* decoder);
+ int (*handle_frame) (void* decoder, void* frame);
+ int (*sink_event) (void* decoder, void* event);
+ int (*src_event) (void* decoder, void* event);
+ int (*negotiate) (void* decoder);
+ int (*decide_allocation) (void* decoder, void* query);
+ int (*propose_allocation) (void* decoder, void* query);
+ int (*flush) (void* decoder);
+ int (*sink_query) (void* decoder, void* query);
+ int (*src_query) (void* decoder, void* query);
+ void* (*getcaps) (void* decoder, void* filter);
+ int (*drain) (void* decoder);
+ int (*transform_meta) (void* decoder, void* frame, void* meta);
+ int (*handle_missing_data) (void* decoder, uint64_t timestamp, uint64_t duration);
+ void* padding[20-7];
+} my_GstVideoDecoderClass_t;
+
+typedef struct my_GstVideoEncoder_s
+{
+ my_GstElement_t parent;
+ void* sinkpad; // GstPad
+ void* srcpad; // GstPad
+ my_GRecMutex_t stream_lock;
+ my_GstSegment_t input_segment;
+ my_GstSegment_t output_segment;
+ void* priv;
+ void* padding[20];
+} my_GstVideoEncoder_t;
+
+typedef struct my_GstVideoEncoderClass_s {
+ my_GstElementClass_t parent_class;
+ int (*open) (void* encoder);
+ int (*close) (void* encoder);
+ int (*start) (void* encoder);
+ int (*stop) (void* encoder);
+ int (*set_format) (void* encoder, void* state);
+ int (*handle_frame) (void* encoder, void* frame);
+ int (*reset) (void* encoder, int hard);
+ int (*finish) (void* encoder);
+ int (*pre_push) (void* encoder, void* frame);
+ void* (*getcaps) (void* encoder, void* filter);
+ int (*sink_event) (void* encoder, void* event);
+ int (*src_event) (void* encoder, void* event);
+ int (*negotiate) (void* encoder);
+ int (*decide_allocation) (void* encoder, void* query);
+ int (*propose_allocation) (void* encoder, void* query);
+ int (*flush) (void* encoder);
+ int (*sink_query) (void* encoder, void* query);
+ int (*src_query) (void* encoder, void* query);
+ int (*transform_meta) (void* encoder, void* frame, void* meta);
+ void* _gst_reserved[20-4];
+} my_GstVideoEncoderClass_t;
+
+typedef struct my_GstBaseSink_s
+{
+ my_GstElement_t parent;
+ void* sinkpad; // GstPad
+ int pad_mode;
+ uint64_t offset;
+ int can_activate_pull;
+ int can_activate_push;
+ my_GMutex_t preroll_lock;
+ my_GCond_t preroll_cond;
+ int eos;
+ int need_preroll;
+ int have_preroll;
+ int playing_async;
+ int have_newsegment;
+ my_GstSegment_t segment;
+ int clock_id;
+ int sync;
+ int flushing;
+ int running;
+ int64_t max_lateness;
+ void* priv;
+ void* _gst_reserved[20];
+} my_GstBaseSink_t;
+
+typedef struct my_GstBaseSinkClass_s {
+ my_GstElementClass_t parent_class;
+ void* (*get_caps) (void* sink, void* filter);
+ int (*set_caps) (void* sink, void* caps);
+ void* (*fixate) (void* sink, void* caps);
+ int (*activate_pull) (void* sink, int active);
+ void (*get_times) (void* sink, void* buffer, void* start, void* end);
+ int (*propose_allocation) (void* sink, void* query);
+ int (*start) (void* sink);
+ int (*stop) (void* sink);
+ int (*unlock) (void* sink);
+ int (*unlock_stop) (void* sink);
+ int (*query) (void* sink, void* query);
+ int (*event) (void* sink, void* event);
+ int (*wait_event) (void* sink, void* event);
+ int (*prepare) (void* sink, void* buffer);
+ int (*prepare_list) (void* sink, void* buffer_list);
+ int (*preroll) (void* sink, void* buffer);
+ int (*render) (void* sink, void* buffer);
+ int (*render_list) (void* sink, void* buffer_list);
+ void* _gst_reserved[20];
+} my_GstBaseSinkClass_t;
+
+typedef struct my_GstVideoSink_s
+{
+ my_GstBaseSink_t parent;
+ int width, height;
+ void* priv;
+ void* _gst_reserved[4];
+} my_GstVideoSink_t;
+
+typedef struct my_GstVideoSinkClass_s
+{
+ my_GstBaseSinkClass_t parent_class;
+ int (*show_frame) (void* video_sink, void* buf);
+ int (*set_info) (void* video_sink, void* caps, void* info);
+ void* _gst_reserved[4-1];
+} my_GstVideoSinkClass_t;
+
+typedef struct my_GstGLBaseFilter_s
+{
+ my_GstBaseTransform_t parent;
+ void* display; // GstGLDisplay
+ void* context; // GstGLContext
+ void* in_caps; // GstCaps
+ void* out_caps; // GstCaps
+ void* _padding[4];
+ void* priv;
+} my_GstGLBaseFilter_t;
+
+typedef struct my_GstGLBaseFilterClass_s
+{
+ my_GstBaseTransformClass_t parent_class;
+ int supported_gl_api;
+ int (*gl_start) (void* filter);
+ void (*gl_stop) (void* filter);
+ int (*gl_set_caps) (void* filter, void* incaps, void* outcaps);
+ void* _padding[4];
+} my_GstGLBaseFilterClass_t;
+
+typedef struct my_GstVideoColorimetry_t
+{
+ int range;
+ int matrix;
+ int transfer;
+ int primaries;
+} my_GstVideoColorimetry_t;
+
+typedef struct my_GstVideoInfo_s
+{
+ void* finfo; // const GstVideoFormatInfo
+ int interlace_mode;
+ int flags;
+ int width;
+ int height;
+ size_t size;
+ int views;
+ int chroma_site;
+ my_GstVideoColorimetry_t colorimetry;
+ int par_n;
+ int par_d;
+ int fps_n;
+ int fps_d;
+ size_t offset[4];
+ int stride[4];
+ union {
+ struct {
+ int multiview_mode;
+ int multiview_flags;
+ int field_order;
+ } abi;
+ void* _gst_reserved[4];
+ } ABI;
+} my_GstVideoInfo_t;
+
+typedef struct my_GstGLFilter_s
+{
+ my_GstGLBaseFilter_t parent;
+ my_GstVideoInfo_t in_info;
+ my_GstVideoInfo_t out_info;
+ int in_texture_target;
+ int out_texture_target;
+ void* out_caps; // GstCaps
+ void* fbo; // GstGLFramebuffer
+ int gl_result;
+ void* inbuf; // GstBuffer
+ void* outbuf; // GstBuffer
+ void* default_shader; // GstGLShader
+ int valid_attributes;
+ uint32_t vao;
+ uint32_t vbo_indices;
+ uint32_t vertex_buffer;
+ int draw_attr_position_loc;
+ int draw_attr_texture_loc;
+ void* _padding[4];
+} my_GstGLFilter_t;
+
+typedef struct my_GstGLFilterClass_s
+{
+ my_GstGLBaseFilterClass_t parent_class;
+ int (*set_caps) (void* filter, void* incaps, void* outcaps);
+ int (*filter) (void* filter, void* inbuf, void* outbuf);
+ int (*filter_texture) (void* filter, void* input, void* output);
+ int (*init_fbo) (void* filter);
+ void* (*transform_internal_caps) (void* filter, int direction, void* caps, void* filter_caps);
+ void* _padding[4];
+} my_GstGLFilterClass_t;
+
+typedef struct my_GstAggregator_s
+{
+ my_GstElement_t parent;
+ void* srcpad; // GstPad
+ void* priv;
+ void* _gst_reserved[20];
+} my_GstAggregator_t;
+
+typedef struct my_GstAggregatorClass_s {
+ my_GstElementClass_t parent_class;
+ int (*flush) (void* self);
+ void* (*clip) (void* self, void* aggregator_pad, void* buf);
+ int (*finish_buffer) (void* self, void* buffer);
+ int (*sink_event) (void* self, void* aggregator_pad, void* event);
+ int (*sink_query) (void* self, void* aggregator_pad, void* query);
+ int (*src_event) (void* self, void* event);
+ int (*src_query) (void* self, void* query);
+ int (*src_activate) (void* self, int mode, int active);
+ int (*aggregate) (void* self, int timeout);
+ int (*stop) (void* self);
+ int (*start) (void* self);
+ uint64_t (*get_next_time) (void* self);
+ void* (*create_new_pad) (void* self, void* templ, void* req_name, void* caps);
+ int (*update_src_caps) (void* self, void* caps, void* ret);
+ void* (*fixate_src_caps) (void* self, void* caps);
+ int (*negotiated_src_caps) (void* self, void* caps);
+ int (*decide_allocation) (void* self, void* query);
+ int (*propose_allocation) (void* self, void*pad, void* decide_query, void* query);
+ int (*negotiate) (void* self);
+ int (*sink_event_pre_queue) (void* self, void* aggregator_pad, void* event);
+ int (*sink_query_pre_queue) (void* self, void* aggregator_pad, void* query);
+ int (*finish_buffer_list) (void* self, void* bufferlist);
+ void (*peek_next_sample) (void* self, void* aggregator_pad);
+ void* _gst_reserved[20-5];
+} my_GstAggregatorClass_t;
+
+typedef struct my_GstVideoAggregator_s
+{
+ my_GstAggregator_t aggregator;
+ my_GstVideoInfo_t info;
+ void* priv;
+ void* _gst_reserved[20];
+} my_GstVideoAggregator_t;
+
+typedef struct my_GstVideoAggregatorClass_s
+{
+ my_GstAggregatorClass_t parent_class;
+ void* (*update_caps) (void* vagg, void* caps);
+ int (*aggregate_frames) (void* vagg, void* outbuffer);
+ int (*create_output_buffer) (void* vagg, void* outbuffer);
+ void (*find_best_format) (void* vagg, void* downstream_caps, void* best_info, void* at_least_one_alpha);
+ void* _gst_reserved[20];
+} my_GstVideoAggregatorClass_t;
+
+typedef struct my_GHookList_s
+{
+ unsigned long seq_id;
+ uint32_t hook_size : 16;
+ uint32_t is_setup : 1;
+ void* hooks; // GHook
+ void* dummy3;
+ void (*finalize_hook) (void* hook_list, void* hook);
+ void* dummy[2];
+} my_GHookList_t;
+
+typedef struct my_GstPad_s
+{
+ my_GstObject_t parent;
+ void* element_private;
+ void* padtemplate; // GstPadTemplate
+ int direction;
+ my_GRecMutex_t stream_rec_lock;
+ void* task; // GstTask
+ my_GCond_t block_cond;
+ my_GHookList_t probes;
+ int mode;
+ int (*activatefunc) (void* pad, void* parent);
+ void* activatedata;
+ void (*activatenotify) (void* a);
+ int (*activatemodefunc) (void* pad, void* parent, int mode, int active);
+ void* activatemodedata;
+ void (*activatemodenotify) (void* a);
+ void* peer; // GstPad
+ int (*linkfunc) (void* pad, void* parent, void* peer);
+ void* linkdata;
+ void (*linknotify) (void* a);
+ void (*unlinkfunc) (void* pad, void* parent);
+ void* unlinkdata;
+ void (*unlinknotify) (void* a);
+ int (*chainfunc) (void* pad, void* parent, void* buffer);
+ void* chaindata;
+ void (*chainnotify) (void* a);
+ int (*chainlistfunc) (void* pad, void* parent, void* list);
+ void* chainlistdata;
+ void (*chainlistnotify) (void* a);
+ int (*getrangefunc) (void* pad, void* parent, uint64_t offset, uint32_t length, void* buffer);
+ void* getrangedata;
+ void (*getrangenotify) (void* a);
+ int (*eventfunc) (void* pad, void* parent, void* event);
+ void* eventdata;
+ void (*eventnotify) (void* a);
+ int64_t offset;
+ int (*queryfunc) (void* pad, void* parent, void* query);
+ void* querydata;
+ void (*querynotify) (void* a);
+ void* (*iterintlinkfunc) (void* pad, void* parent);
+ void* iterintlinkdata;
+ void (*iterintlinknotify) (void* a);
+ int num_probes;
+ int num_blocked;
+ void* priv;
+ union {
+ void* _gst_reserved[4];
+ struct {
+ int last_flowret;
+ int (*eventfullfunc) (void* pad, void* parent, void* event);
+ } abi;
+ } ABI;
+} my_GstPad_t;
+
+typedef struct my_GstPadClass_s {
+ my_GstObjectClass_t parent_class;
+ void (*linked) (void* pad, void* peer);
+ void (*unlinked) (void* pad, void* peer);
+ void* _gst_reserved[4];
+} my_GstPadClass_t;
+
+typedef struct my_GstAggregatorPad_s
+{
+ my_GstPad_t parent;
+ my_GstSegment_t segment;
+ void* priv;
+ void* _gst_reserved[4];
+} my_GstAggregatorPad_t;
+
+typedef struct my_GstAggregatorPadClass_s
+{
+ my_GstPadClass_t parent_class;
+ int (*flush) (void* aggpad, void* aggregator);
+ int (*skip_buffer) (void* aggpad, void* aggregator, void* buffer);
+ void* _gst_reserved[20];
+} my_GstAggregatorPadClass_t;
+
+typedef struct my_GstVideoAggregatorPad_s
+{
+ my_GstAggregatorPad_t parent;
+ my_GstVideoInfo_t info;
+ void* priv;
+ void* _gst_reserved[4];
+} my_GstVideoAggregatorPad_t;
+
+typedef struct my_GstVideoAggregatorPadClass_s
+{
+ my_GstAggregatorPadClass_t parent_class;
+ void (*update_conversion_info) (void* pad);
+ int (*prepare_frame) (void* pad, void* vagg, void* buffer, void* prepared_frame);
+ void (*clean_frame) (void* pad, void* vagg, void* prepared_frame);
+ void (*prepare_frame_start) (void* pad, void* vagg, void* buffer, void* prepared_frame);
+ void (*prepare_frame_finish) (void* pad, void* vagg, void* prepared_frame);
+ void* _gst_reserved[20-2];
+} my_GstVideoAggregatorPadClass_t;
+
+typedef struct my_GstBaseSrc_s
+{
+ my_GstElement_t parent;
+ void* srcpad; // GstPad
+ my_GMutex_t live_lock;
+ my_GCond_t live_cond;
+ int is_live;
+ int live_running;
+ uint32_t blocksize;
+ int can_activate_push;
+ int random_access;
+ int clock_id;
+ my_GstSegment_t segment;
+ int need_newsegment;
+ int num_buffers;
+ int num_buffers_left;
+ int typefind;
+ int running;
+ void* pending_seek; // GstEvent
+ void* priv;
+ void* _gst_reserved[20];
+} my_GstBaseSrc_t;
+
+typedef struct my_GstBaseSrcClass_s {
+ my_GstElementClass_t parent_class;
+ void* (*get_caps) (void* src, void* filter);
+ int (*negotiate) (void* src);
+ void* (*fixate) (void* src, void* caps);
+ int (*set_caps) (void* src, void* caps);
+ int (*decide_allocation) (void* src, void* query);
+ int (*start) (void* src);
+ int (*stop) (void* src);
+ void (*get_times) (void* src, void* buffer, void* start, void* end);
+ int (*get_size) (void* src, void* size);
+ int (*is_seekable) (void* src);
+ int (*prepare_seek_segment) (void* src, void* seek, void* segment);
+ int (*do_seek) (void* src, void* segment);
+ int (*unlock) (void* src);
+ int (*unlock_stop) (void* src);
+ int (*query) (void* src, void* query);
+ int (*event) (void* src, void* event);
+ int (*create) (void* src, uint64_t offset, uint32_t size, void* buf);
+ int (*alloc) (void* src, uint64_t offset, uint32_t size, void* buf);
+ int (*fill) (void* src, uint64_t offset, uint32_t size, void* buf);
+ void* _gst_reserved[20];
+} my_GstBaseSrcClass_t;
+
+typedef struct my_GstPushSrc_s
+{
+ my_GstBaseSrc_t parent;
+ void* _gst_reserved[4];
+} my_GstPushSrc_t;
+
+typedef struct my_GstPushSrcClass_s {
+ my_GstBaseSrcClass_t parent_class;
+ int (*create) (void* src, void* buf);
+ int (*alloc) (void* src, void* buf);
+ int (*fill) (void* src, void* buf);
+ void* _gst_reserved[4];
+} my_GstPushSrcClass_t;
+
+typedef struct my_GstGLBaseSrc_s
+{
+ my_GstPushSrc_t parent;
+ void* display; // GstGLDisplay
+ void* context; // GstGLContext
+ my_GstVideoInfo_t out_info;
+ void* out_caps; // GstCaps
+ uint64_t running_time;
+ void* _padding[4];
+ void* priv;
+} my_GstGLBaseSrc_t;
+
+typedef struct my_GstGLBaseSrcClass_s {
+ my_GstPushSrcClass_t parent_class;
+ int supported_gl_api;
+ int (*gl_start) (void* src);
+ void (*gl_stop) (void* src);
+ int (*fill_gl_memory) (void* src, void* mem);
+ void* _padding[4];
+} my_GstGLBaseSrcClass_t;
+
+typedef struct my_GstAudioDecoder_s
+{
+ my_GstElement_t parent;
+ void* sinkpad; // GstPad
+ void* srcpad; // GstPad
+ my_GRecMutex_t stream_lock;
+ my_GstSegment_t input_segment;
+ my_GstSegment_t output_segment;
+ void* priv;
+ void* _gst_reserved[20];
+} my_GstAudioDecoder_t;
+
+typedef struct my_GstAudioDecoderClass_s
+{
+ my_GstElementClass_t parent_class;
+ int (*start) (void* dec);
+ int (*stop) (void* dec);
+ int (*set_format) (void* dec, void* caps);
+ int (*parse) (void* dec, void* adapter, void* offset, void* length);
+ int (*handle_frame) (void* dec, void* buffer);
+ void (*flush) (void* dec, int hard);
+ int (*pre_push) (void* dec, void* buffer);
+ int (*sink_event) (void* dec, void* event);
+ int (*src_event) (void* dec, void* event);
+ int (*open) (void* dec);
+ int (*close) (void* dec);
+ int (*negotiate) (void* dec);
+ int (*decide_allocation) (void* dec, void* query);
+ int (*propose_allocation) (void* dec, void* query);
+ int (*sink_query) (void* dec, void* query);
+ int (*src_query) (void* dec, void* query);
+ void* (*getcaps) (void* dec, void* filter);
+ int (*transform_meta) (void* enc, void* outbuf, void* meta, void* inbuf);
+ void* _gst_reserved[20 - 4];
+} my_GstAudioDecoderClass_t;
+
+typedef struct my_GstVideoFilter_s {
+ my_GstBaseTransform_t parent;
+ int negotiated;
+ my_GstVideoInfo_t in_info;
+ my_GstVideoInfo_t out_info;
+ void* _gst_reserved[4];
+} my_GstVideoFilter_t;
+
+typedef struct my_GstVideoFilterClass_s {
+ my_GstBaseTransformClass_t parent_class;
+ int (*set_info) (void* filter, void* incaps, void* in_info, void* outcaps, void* out_info);
+ int (*transform_frame) (void* filter, void* inframe, void* outframe);
+ int (*transform_frame_ip) (void* filter, void* frame);
+ void* _gst_reserved[4];
+} my_GstVideoFilterClass_t;
+
+typedef struct my_GDBusProxy_s
+{
+ my_GObject_t parent;
+ void* priv;
+} my_GDBusProxy_t;
+
typedef struct my_GDBusProxyClass_s {
my_GObjectClass_t parent_class;
void (*g_properties_changed) (void* proxy, void* changed_properties, const char* const* invalidated_properties);
@@ -795,6 +2094,20 @@ typedef struct my_GDBusProxyClass_s {
void* padding[32];
} my_GDBusProxyClass_t;
+typedef struct my_GTypeInterface_s {
+ size_t g_type;
+ size_t g_instance_type;
+} my_GTypeInterface_t;
+
+typedef struct my_GstURIHandlerInterface_s {
+ my_GTypeInterface_t parent;
+ int (* get_type) (size_t type);
+ void* (* get_protocols) (size_t type);
+ void* (* get_uri) (void* handler);
+ int (* set_uri) (void* handler, void* uri, void* error);
+} my_GstURIHandlerInterface_t;
+
+
// GTypeValueTable
typedef struct my_GTypeValueTable_s {
void (*value_init) (void* value);
@@ -852,7 +2165,6 @@ void FiniGTKClass(void);
#define GTKCLASSES() \
GTKCLASS(GObject) \
GTKCLASS(GInitiallyUnowned) \
-GTKCLASS(GamesScoresImporter) \
GTKCLASS(GApplication) \
GTKCLASS(GtkApplication) \
GTKCLASS(GtkObject) \
@@ -865,6 +2177,7 @@ GTKCLASS(GtkLabel2) \
GTKCLASS(GtkLabel3) \
GTKCLASS(GtkMisc2) \
GTKCLASS(GtkMisc3) \
+GTKCLASS(GtkImage3) \
GTKCLASS(GtkTreeView2) \
GTKCLASS(GtkBin2) \
GTKCLASS(GtkBin3) \
@@ -872,6 +2185,7 @@ GTKCLASS(GtkWindow2) \
GTKCLASS(GtkWindow3) \
GTKCLASS(GtkTable2) \
GTKCLASS(GtkFixed2) \
+GTKCLASS(GtkFixed3) \
GTKCLASS(GtkApplicationWindow) \
GTKCLASS(GtkListBox) \
GTKCLASS(GtkListBoxRow) \
@@ -879,7 +2193,10 @@ GTKCLASS(GtkButton2) \
GTKCLASS(GtkButton3) \
GTKCLASS(GtkComboBox2) \
GTKCLASS(GtkToggleButton2) \
+GTKCLASS(GtkToggleButton3) \
+GTKCLASS(GtkMenuButton3) \
GTKCLASS(GtkCheckButton2) \
+GTKCLASS(GtkCheckButton3) \
GTKCLASS(GtkEntry2) \
GTKCLASS(GtkSpinButton2) \
GTKCLASS(GtkProgress2) \
@@ -902,18 +2219,50 @@ GTKCLASS(GstObject) \
GTKCLASS(GstAllocator) \
GTKCLASS(GstTaskPool) \
GTKCLASS(GDBusProxy) \
+GTKCLASS(GstElement) \
+GTKCLASS(GstBin) \
+GTKCLASS(GstBaseTransform) \
+GTKCLASS(GstVideoDecoder) \
+GTKCLASS(GstVideoEncoder) \
+GTKCLASS(GstBaseSink) \
+GTKCLASS(GstVideoSink) \
+GTKCLASS(GstGLBaseFilter) \
+GTKCLASS(GstGLFilter) \
+GTKCLASS(GstAggregator) \
+GTKCLASS(GstVideoAggregator) \
+GTKCLASS(GstPad) \
+GTKCLASS(GstAggregatorPad) \
+GTKCLASS(GstVideoAggregatorPad) \
+GTKCLASS(GstBaseSrc) \
+GTKCLASS(GstPushSrc) \
+GTKCLASS(GstGLBaseSrc) \
+GTKCLASS(GstAudioDecoder) \
+GTKCLASS(GstVideoFilter) \
+GTKIFACE(GstURIHandler) \
#define GTKCLASS(A) void Set##A##ID(size_t id);
+#define GTKIFACE(A) GTKCLASS(A)
GTKCLASSES()
+#undef GTKIFACE
#undef GTKCLASS
void SetGTypeName(void* f);
+void SetGTypeParent(void* f);
void SetGClassPeek(void* f);
void AutoBridgeGtk(void*(*ref)(size_t), void(*unref)(void*));
void* wrapCopyGTKClass(void* cl, size_t type);
void* unwrapCopyGTKClass(void* klass, size_t type);
+void unwrapGTKInterface(void* cl, size_t type);
+void* wrapCopyGTKInterface(void* cl, size_t type);
+void* unwrapCopyGTKInterface(void* iface, size_t type);
+
+void unwrapGTKInstance(void* cl, size_t type);
+void bridgeGTKInstance(void* cl, size_t type);
+
+void addRegisteredClass(size_t klass, char* name);
+
typedef struct my_signal_s {
uint64_t sign; // signature
void* data;
diff --git a/src/include/librarian.h b/src/include/librarian.h
index 6fc8932..13cb389 100644
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -37,6 +37,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, const char* defver);
void MapLibRemoveLib(lib_t* maplib, library_t* lib);
+void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref);
const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, const char* symname);
diff --git a/src/include/myalign.h b/src/include/myalign.h
index 247ea1b..9293139 100644
--- a/src/include/myalign.h
+++ b/src/include/myalign.h
@@ -214,4 +214,26 @@ void AlignSemidDs(void *dest, const void* source);
uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N);
+// longjmp / setjmp
+typedef struct jump_buff_x64_s {
+ uint64_t save_rbx;
+ uint64_t save_rbp;
+ uint64_t save_r12;
+ uint64_t save_r13;
+ uint64_t save_r14;
+ uint64_t save_r15;
+ uint64_t save_rsp;
+ uint64_t save_rip;
+} jump_buff_x64_t;
+
+typedef struct __jmp_buf_tag_s {
+ jump_buff_x64_t __jmpbuf;
+ int __mask_was_saved;
+ #ifdef ANDROID
+ sigset_t __saved_mask;
+ #else
+ __sigset_t __saved_mask;
+ #endif
+} __jmp_buf_tag_t;
+
#endif //__MY_ALIGN__H_
diff --git a/src/include/regs.h b/src/include/regs.h
index a80b393..dc72a64 100644
--- a/src/include/regs.h
+++ b/src/include/regs.h
@@ -139,7 +139,13 @@ typedef enum {
d_inc16i,
d_inc32i,
d_inc64i,
- d_unknown //95
+ d_shrd16,
+ d_shrd32,
+ d_shrd64,
+ d_shld16,
+ d_shld32,
+ d_shld64,
+ d_unknown //101
} deferred_flags_t;
#pragma pack(push, 1)
@@ -353,6 +359,44 @@ typedef union {
#define R_ES emu->segs[_ES]
#define R_FS emu->segs[_FS]
#define R_GS emu->segs[_GS]
+#define S_RAX emu->regs[_AX].sq[0]
+#define S_RBX emu->regs[_BX].sq[0]
+#define S_RCX emu->regs[_CX].sq[0]
+#define S_RDX emu->regs[_DX].sq[0]
+#define S_RDI emu->regs[_DI].sq[0]
+#define S_RSI emu->regs[_SI].sq[0]
+#define S_RSP emu->regs[_SP].sq[0]
+#define S_RBP emu->regs[_BP].sq[0]
+#define S_R8 emu->regs[_R8].sq[0]
+#define S_R9 emu->regs[_R9].sq[0]
+#define S_R10 emu->regs[_R10].sq[0]
+#define S_R11 emu->regs[_R11].sq[0]
+#define S_R12 emu->regs[_R12].sq[0]
+#define S_R13 emu->regs[_R13].sq[0]
+#define S_R14 emu->regs[_R14].sq[0]
+#define S_R15 emu->regs[_R15].sq[0]
+#define S_EAX emu->regs[_AX].sdword[0]
+#define S_EBX emu->regs[_BX].sdword[0]
+#define S_ECX emu->regs[_CX].sdword[0]
+#define S_EDX emu->regs[_DX].sdword[0]
+#define S_EDI emu->regs[_DI].sdword[0]
+#define S_ESI emu->regs[_SI].sdword[0]
+#define S_ESP emu->regs[_SP].sdword[0]
+#define S_EBP emu->regs[_BP].sdword[0]
+#define S_R8d emu->regs[_R8].sdword[0]
+#define S_R9d emu->regs[_R9].sdword[0]
+#define S_R10d emu->regs[_R10].sdword[0]
+#define S_AX emu->regs[_AX].sword[0]
+#define S_BX emu->regs[_BX].sword[0]
+#define S_CX emu->regs[_CX].sword[0]
+#define S_DX emu->regs[_DX].sword[0]
+#define S_DI emu->regs[_DI].sword[0]
+#define S_SI emu->regs[_SI].sword[0]
+#define S_SP emu->regs[_SP].sword[0]
+#define S_BP emu->regs[_BP].sword[0]
+#define S_AL emu->regs[_AX].sbyte[0]
+#define S_AH emu->regs[_AX].sbyte[1]
+#define S_CL emu->regs[_CX].sbyte[0]
#define ACCESS_FLAG(F) emu->eflags.f._##F
#define SET_FLAG(F) emu->eflags.f._##F = 1
diff --git a/src/include/signals.h b/src/include/signals.h
index 3fe8a2f..deda21f 100644
--- a/src/include/signals.h
+++ b/src/include/signals.h
@@ -38,5 +38,6 @@ void fini_signal_helper(void);
void emit_signal(x64emu_t* emu, int sig, void* addr, int code);
void emit_interruption(x64emu_t* emu, int num, void* addr);
+void emit_div0(x64emu_t* emu, void* addr, int code);
#endif //__SIGNALS_H__
diff --git a/src/include/super80.h b/src/include/super80.h
new file mode 100644
index 0000000..b6f7f96
--- /dev/null
+++ b/src/include/super80.h
@@ -0,0 +1,82 @@
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3) \
+GO(4) \
+GO(5) \
+GO(6) \
+GO(7) \
+GO(8) \
+GO(9) \
+GO(10) \
+GO(11) \
+GO(12) \
+GO(13) \
+GO(14) \
+GO(15) \
+GO(16) \
+GO(17) \
+GO(18) \
+GO(19) \
+GO(20) \
+GO(21) \
+GO(22) \
+GO(23) \
+GO(24) \
+GO(25) \
+GO(26) \
+GO(27) \
+GO(28) \
+GO(29) \
+GO(30) \
+GO(31) \
+GO(32) \
+GO(33) \
+GO(34) \
+GO(35) \
+GO(36) \
+GO(37) \
+GO(38) \
+GO(39) \
+GO(40) \
+GO(41) \
+GO(42) \
+GO(43) \
+GO(44) \
+GO(45) \
+GO(46) \
+GO(47) \
+GO(48) \
+GO(49) \
+GO(50) \
+GO(51) \
+GO(52) \
+GO(53) \
+GO(54) \
+GO(55) \
+GO(56) \
+GO(57) \
+GO(58) \
+GO(59) \
+GO(60) \
+GO(61) \
+GO(62) \
+GO(63) \
+GO(64) \
+GO(65) \
+GO(66) \
+GO(67) \
+GO(68) \
+GO(69) \
+GO(70) \
+GO(71) \
+GO(72) \
+GO(73) \
+GO(74) \
+GO(75) \
+GO(76) \
+GO(77) \
+GO(78) \
+GO(79) \
+
diff --git a/src/include/threads.h b/src/include/threads.h
index af58046..8ed0e4c 100644
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -8,6 +8,7 @@ void CleanStackSize(box64context_t* context);
void init_pthread_helper(void);
void fini_pthread_helper(box64context_t* context);
+void clean_current_emuthread(void);
// prepare an "emuthread structure" in pet and return address of function pointer for a "thread creation routine"
void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet);
diff --git a/src/librarian/globalsymbols.c b/src/librarian/globalsymbols.c
index 462af7f..6d96720 100644
--- a/src/librarian/globalsymbols.c
+++ b/src/librarian/globalsymbols.c
@@ -20,7 +20,7 @@
if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) { \
printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A); \
memcpy((void*)globoffs, &A, sizeof(A)); \
- } \
+ } else \
if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, B)) { \
printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A); \
memcpy((void*)globoffs, &A, sizeof(A)); \
@@ -30,7 +30,7 @@
if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) { \
printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A); \
memcpy(&A, (void*)globoffs, sizeof(A)); \
- } \
+ } else \
if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, B)) { \
printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A); \
memcpy(&A, (void*)globoffs, sizeof(A)); \
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index 072ef81..1f103ad 100644
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -41,7 +41,7 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
/*if((*maplib)->ownlibs && (*maplib)->libsz) {
for(int i=0; i<(*maplib)->libsz; ++i) {
- printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
+ printf_dump(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
DecRefCount(&(*maplib)->libraries[i], emu);
}
}*/
@@ -105,6 +105,28 @@ void MapLibAddLib(lib_t* maplib, library_t* lib)
++maplib->libsz;
}
+void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref)
+{
+ if(libraryInMapLib(maplib, lib))
+ return;
+ if (maplib->libsz == maplib->libcap) {
+ maplib->libcap += 8;
+ maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
+ }
+ // find insersion point
+ int point = ref?maplib->libsz:0;
+ if(ref)
+ for(int i=0; i<maplib->libsz; ++i)
+ if(maplib->libraries[i]==ref) {
+ point = i;
+ i = maplib->libsz;
+ }
+ if(point<maplib->libsz)
+ memmove(&maplib->libraries[point+1], &maplib->libraries[point], sizeof(library_t*)*(maplib->libsz-point));
+ maplib->libraries[point] = lib;
+ ++maplib->libsz;
+}
+
static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src)
{
if(!src)
@@ -177,34 +199,31 @@ int isLibLocal(library_t* lib)
return libraryInMapLib(my_context->local_maplib, lib);
}
-static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int n, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
+static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, int n, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
{
const char* path = needed->names[n];
- printf_log(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":"");
+ printf_dump(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":"");
// first check if lib is already loaded
library_t *lib = getLib(my_context->maplib, path);
if(lib) {
IncRefCount(lib, emu); // increment cntref
needed->libs[n] = lib;
- printf_log(LOG_DEBUG, "Already present in maplib => success\n");
+ printf_dump(LOG_DEBUG, "Already present in maplib => success\n");
return 0;
}
// check also in the local loaded lib
lib = getLib(my_context->local_maplib, path);
if(lib) {
- printf_log(LOG_DEBUG, "Already present in local_maplib => success\n");
+ printf_dump(LOG_DEBUG, "Already present in local_maplib => success\n");
needed->libs[n] = lib;
IncRefCount(lib, emu); // increment cntref
if(local) {
// add lib to maplib...
- if(maplib) {
- if(lib->maplib) {
- MapLibAddMapLib(maplib, lib, lib->maplib);
- }
- if(!libraryInMapLib(maplib, lib))
- MapLibAddLib(maplib, lib);
- if(maplib->ownlibs)
- MapLibRemoveMapLib(my_context->local_maplib, maplib);
+ if(*maplib) {
+ if(!libraryInMapLib(*maplib, lib))
+ MapLibPrependLib(*maplib, lib, NULL); // todo: Also insert libs needed by lib, after lib? But current lib->maplib is probably not the solution
+ if((*maplib)->ownlibs)
+ MapLibRemoveMapLib(my_context->local_maplib, *maplib);
}
} else {
// promote lib from local to global...
@@ -215,17 +234,15 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
// load a new one
needed->libs[n] = lib = NewLibrary(path, box64, verneeded);
if(!lib) {
- printf_log(LOG_DEBUG, "Faillure to create lib => fail\n");
+ printf_dump(LOG_DEBUG, "Faillure to create lib => fail\n");
return 1; //Error
}
// add lib now
if(local) {
MapLibAddLib(my_context->local_maplib, lib);
- if(maplib) {
- MapLibAddLib(maplib, lib);
- if(!lib->maplib)
- lib->maplib = maplib;
+ if(*maplib) {
+ MapLibAddLib(*maplib, lib);
} else {
lib->maplib = NewLibrarian(box64, 0);
MapLibAddLib(lib->maplib, lib);
@@ -234,11 +251,11 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
MapLibAddLib(my_context->maplib, lib);
}
- if(!maplib)
- maplib = (local)?lib->maplib:my_context->maplib;
+ if(!*maplib)
+ *maplib = (local)?lib->maplib:my_context->maplib;
- if(AddSymbolsLibrary(maplib, lib, emu)) { // also add needed libs
- printf_log(LOG_DEBUG, "Failure to Add lib => fail\n");
+ if(AddSymbolsLibrary(*maplib, lib, emu)) { // also add needed libs
+ printf_dump(LOG_DEBUG, "Failure to Add lib => fail\n");
return 1;
}
@@ -247,7 +264,7 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
linkmap_t *lm = addLinkMapLib(lib);
if(!lm) {
// Crashed already
- printf_log(LOG_DEBUG, "Failure to add lib linkmap\n");
+ printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
return 1;
}
lm->l_addr = (Elf64_Addr)GetElfDelta(lib->e.elf);
@@ -272,7 +289,7 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
// it's an emulated lib,
// load dependancies and launch init sequence
if(LoadNeededLibs(mainelf, maplib, 0, bindnow, box64, emu)) {
- printf_log(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
+ printf_dump(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
return 1;
}
// some special case, where dependancies may not be correct
@@ -297,12 +314,12 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
// finalize the lib
if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, emu)) {
- printf_log(LOG_DEBUG, "Failure to finalizing lib => fail\n");
+ printf_dump(LOG_DEBUG, "Failure to finalizing lib => fail\n");
return 1;
}
}
// success
- printf_log(LOG_DEBUG, "Created lib and added to maplib => success\n");
+ printf_dump(LOG_DEBUG, "Created lib and added to maplib => success\n");
return 0;
}
@@ -326,7 +343,7 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, e
int ret = 0;
// Add libs and symbol
for(int i=0; i<needed->size; ++i) {
- if(AddNeededLib_add(maplib, local, needed, i, verneeded, box64, emu)) {
+ if(AddNeededLib_add(&maplib, local, needed, i, verneeded, box64, emu)) {
printf_log(strchr(needed->names[i],'/')?LOG_DEBUG:LOG_INFO, "Error loading needed lib %s\n", needed->names[i]);
ret = 1;
}
@@ -351,20 +368,20 @@ void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64conte
return;
for(int i=0; i<needed->size; ++i) {
if(box64_log>=LOG_DEBUG && needed->libs[i])
- printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
+ printf_dump(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu);
}
}
library_t* GetLibMapLib(lib_t* maplib, const char* name)
{
- printf_log(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
+ printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
return getLib(maplib, name);
}
library_t* GetLibInternal(const char* name)
{
- printf_log(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
+ printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
library_t* lib = getLib(my_context->maplib, name);
if(!lib) lib = getLib(my_context->local_maplib, name);
return lib;
@@ -388,6 +405,20 @@ static int isLocal(elfheader_t* self, library_t* l)
return 0;
}
+static void CheckNeededLibs(needed_libs_t* needed)
+{
+ while(needed->nb_done<needed->size) {
+ library_t* lib = needed->libs[needed->nb_done++];
+ if(lib) {
+ int n = GetNeededLibsN(lib);
+ char** names = GetNeededLibsNames(lib);
+ for (int i=0; i<n; ++i) {
+ add1lib_neededlib(needed, GetNeededLib(lib, i), names[i]);
+ }
+ }
+ }
+}
+
int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver)
{
assert(self); // need self for this one
@@ -449,29 +480,38 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
if(my_context->preload)
for(int i=0; i<my_context->preload->size; ++i)
if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver))
- if(*start)
- return 1;
- // search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
- if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
- if(*start)
- return 1;
- // TODO: create a temporary map to search lib only 1 time, and in order of needed...
- // search in needed libs from neededlibs first, in order
- if(my_context->neededlibs)
- for(int i=0; i<my_context->neededlibs->size; ++i)
- if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver))
- if(*start)
+ if(*start) {
return 1;
+ }
+ if(maplib==my_context->maplib) {
+ // search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
+ if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
+ if(*start) {
+ return 1;
+ }
+ // This kind-of create a map to search lib only 1 time, and in order of needed...
+ if(my_context->neededlibs)
+ CheckNeededLibs(my_context->neededlibs);
+ // search in needed libs from neededlibs first, in order
+ if(my_context->neededlibs)
+ for(int i=0; i<my_context->neededlibs->size; ++i)
+ if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver))
+ if(*start) {
+ return 1;
+ }
+ }
// search in global symbols
if(maplib) {
- if(self && self!=my_context->elfs[0] && self!=(void*)1)
+ if((maplib==my_context->maplib) && self && self!=my_context->elfs[0] && self!=(void*)1)
if(GetSymbolStartEnd(GetMapSymbols(self), name, start, end, version, vername, 1, globdefver))
- if(*start)
+ if(*start) {
return 1;
+ }
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver))
- if(*start)
+ if(*start) {
return 1;
+ }
}
}
@@ -479,14 +519,24 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
int ok = 0;
// GetSymbolStartEnd should not change start/end if symbol is not found
if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, weakdefver))
- if(*start)
+ if(*start) {
ok = 1;
+ }
+
+ // search in needed libs from neededlibs first, in order
+ if(my_context->neededlibs)
+ for(int i=0; i<my_context->neededlibs->size; ++i)
+ if(GetLibWeakSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), weakdefver))
+ if(*start) {
+ return 1;
+ }
if(maplib)
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver))
- if(*start)
+ if(*start) {
ok = 1;
+ }
}
// nope, not found
return (ok && *start)?1:0;
@@ -540,7 +590,9 @@ static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name,
if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
if(*start)
return 1;
- // TODO: create a temporary map to search lib only 1 time, and in order of needed...
+ // This kind-of create a map to search lib only 1 time, and in order of needed...
+ if(my_context->neededlibs)
+ CheckNeededLibs(my_context->neededlibs);
// search in needed libs from neededlibs first, in order
if(my_context->neededlibs)
for(int i=0; i<my_context->neededlibs->size; ++i)
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 18fbe24..407ad50 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -51,7 +51,7 @@ typedef struct bridged_s {
KHASH_MAP_INIT_STR(bridgemap, bridged_t)
-KHASH_MAP_IMPL_STR(symbolmap, wrapper_t)
+KHASH_MAP_IMPL_STR(symbolmap, symbol1_t)
KHASH_MAP_IMPL_STR(symbol2map, symbol2_t)
KHASH_MAP_IMPL_STR(datamap, uint64_t)
@@ -209,7 +209,7 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
printf_log(LOG_NONE, "Error initializing native %s (last dlerror is %s)\n", lib->name, error_str);
return; // non blocker...
}
- printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
+ printf_dump(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
lib->fini = wrappedlibs[i].fini;
lib->getglobal = WrappedLib_GetGlobal;
lib->getweak = WrappedLib_GetWeak;
@@ -225,13 +225,15 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
linkmap_t *lm = addLinkMapLib(lib);
if(!lm) {
// Crashed already
- printf_log(LOG_DEBUG, "Failure to add lib %s linkmap\n", lib->name);
+ printf_dump(LOG_DEBUG, "Failure to add lib %s linkmap\n", lib->name);
break;
}
struct link_map real_lm;
+ #ifndef ANDROID
if(dlinfo(lib->w.lib, RTLD_DI_LINKMAP, &real_lm)) {
- printf_log(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
+ printf_dump(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
}
+ #endif
lm->l_addr = real_lm.l_addr;
lm->l_name = real_lm.l_name;
lm->l_ld = real_lm.l_ld;
@@ -251,7 +253,7 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
}
elfheader_t *elf_header = LoadAndCheckElfHeader(f, libname, 0);
if(!elf_header) {
- printf_log(LOG_DEBUG, "Error: reading elf header of %s\n", libname); // this one can be too alarming...
+ printf_dump(LOG_DEBUG, "Error: reading elf header of %s\n", libname); // this one can be too alarming...
fclose(f);
return 0;
}
@@ -259,25 +261,15 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
if(CalcLoadAddr(elf_header)) {
printf_log(LOG_NONE, "Error: reading elf header of %s\n", libname);
FreeElfHeader(&elf_header);
- fclose(f);
- return 0;
- }
- // allocate memory
- if(AllocElfMemory(context, elf_header, 0)) {
- printf_log(LOG_NONE, "Error: allocating memory for elf %s\n", libname);
- FreeElfHeader(&elf_header);
- fclose(f);
return 0;
}
- // Load elf into memory
- if(LoadElfMemory(f, context, elf_header)) {
- printf_log(LOG_NONE, "Error: loading in memory elf %s\n", libname);
+ // allocate and load elf
+ if(AllocLoadElfMemory(context, elf_header, 0)) {
+ printf_log(LOG_NONE, "Error: loading for elf %s\n", libname);
FreeElfHeader(&elf_header);
- fclose(f);
return 0;
}
// can close the file now
- fclose(f);
if(verneeded && !isElfHasNeededVer(elf_header, lib->name, verneeded)) {
// incompatible, discard and continue the search
FreeElfHeader(&elf_header);
@@ -302,21 +294,25 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
lib->path = box_strdup(libname);
}
- printf_log(LOG_INFO, "Using emulated %s\n", libname);
+ printf_dump(LOG_INFO, "Using emulated %s\n", libname);
#ifdef DYNAREC
if(libname && box64_dynarec_bleeding_edge && strstr(libname, "libmonobdwgc-2.0.so")) {
- printf_log(LOG_INFO, "MonoBleedingEdge detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
+ printf_dump(LOG_INFO, "MonoBleedingEdge detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
box64_dynarec_bigblock = 0;
box64_dynarec_strongmem = 1;
}
if(libname && box64_dynarec_jvm && strstr(libname, "libjvm.so")) {
- printf_log(LOG_INFO, "libjvm detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
+ printf_dump(LOG_INFO, "libjvm detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
box64_dynarec_bigblock = 0;
box64_dynarec_strongmem = 1;
}
+ if(libname && box64_dynarec_tbb && strstr(libname, "libtbb.so")) {
+ printf_dump(LOG_INFO, "libtbb detected, enable Dynarec StrongMem\n");
+ box64_dynarec_strongmem = 3;
+ }
#endif
if(libname && box64_libcef && strstr(libname, "libcef.so")) {
- printf_log(LOG_INFO, "libcef detected, using malloc_hack_2\n");
+ printf_dump(LOG_INFO, "libcef detected, using malloc_hack_2\n");
box64_malloc_hack = 2;
}
return 1;
@@ -370,7 +366,7 @@ static int isEssentialLib(const char* name) {
library_t *NewLibrary(const char* path, box64context_t* context, elfheader_t* verneeded)
{
- printf_log(LOG_DEBUG, "Trying to load \"%s\"\n", path);
+ printf_dump(LOG_DEBUG, "Trying to load \"%s\"\n", path);
library_t *lib = (library_t*)box_calloc(1, sizeof(library_t));
lib->path = box_realpath(path, NULL);
if(!lib->path)
@@ -381,7 +377,7 @@ library_t *NewLibrary(const char* path, box64context_t* context, elfheader_t* ve
lib->name = Path2Name(path);
lib->nbdot = NbDot(lib->name);
lib->type = LIB_UNNKNOW;
- printf_log(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name);
+ printf_dump(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name);
if(box64_nopulse) {
if(strstr(lib->name, "libpulse.so")==lib->name || strstr(lib->name, "libpulse-simple.so")==lib->name) {
box_free(lib->name);
@@ -466,12 +462,12 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t*
int weak;
if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL, NULL, NULL)) {
SetTraceEmu(trace_start, trace_end);
- printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
+ printf_dump(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
box_free(trace_func);
trace_func = NULL;
} else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, -1, NULL, 0, NULL)) {
SetTraceEmu(trace_start, trace_end);
- printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
+ printf_dump(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
box_free(trace_func);
trace_func = NULL;
}
@@ -482,50 +478,6 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t*
return 0;
}
-int ReloadLibrary(library_t* lib, x64emu_t* emu)
-{
- if(lib->type==LIB_EMULATED) {
- elfheader_t *elf_header = lib->e.elf;
- // reload image in memory and re-run the mapping
- char libname[MAX_PATH];
- strcpy(libname, lib->path);
- int found = FileExist(libname, IS_FILE);
- if(!found && !strchr(lib->path, '/'))
- for(int i=0; i<my_context->box64_ld_lib.size; ++i)
- {
- strcpy(libname, my_context->box64_ld_lib.paths[i]);
- strcat(libname, lib->path);
- if(FileExist(libname, IS_FILE))
- break;
- }
- if(!FileExist(libname, IS_FILE)) {
- printf_log(LOG_NONE, "Error: open file to re-load elf %s\n", libname);
- return 1; // failed to reload...
- }
- FILE *f = fopen(libname, "rb");
- if(!f) {
- printf_log(LOG_NONE, "Error: cannot open file to re-load elf %s (errno=%d/%s)\n", libname, errno, strerror(errno));
- return 1; // failed to reload...
- }
- if(ReloadElfMemory(f, my_context, elf_header)) {
- printf_log(LOG_NONE, "Error: re-loading in memory elf %s\n", libname);
- fclose(f);
- return 1;
- }
- // can close the file now
- fclose(f);
- // should bindnow be store in a per/library basis?
- if(RelocateElf(my_context->maplib, lib->maplib, 0, elf_header)) {
- printf_log(LOG_NONE, "Error: relocating symbols in elf %s\n", lib->name);
- return 1;
- }
- RelocateElfPlt(my_context->maplib, lib->maplib, 0, elf_header);
- // init (will use PltRelocator... because some other libs are not yet resolved)
- RunElfInit(elf_header, emu);
- }
- return 0;
-}
-
int FiniLibrary(library_t* lib, x64emu_t* emu)
{
switch (lib->type) {
@@ -544,7 +496,7 @@ void Free1Library(library_t **the_lib, x64emu_t* emu)
library_t* lib = *the_lib;
- printf_log(LOG_DEBUG, "Free1Library %s\n", lib->name);
+ printf_dump(LOG_DEBUG, "Free1Library %s\n", lib->name);
// remove lib from maplib/local_maplib...
if(my_context) {
MapLibRemoveLib(my_context->maplib, lib);
@@ -619,6 +571,11 @@ char* GetNameLib(library_t* lib)
{
return lib->name;
}
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
int IsSameLib(library_t* lib, const char* path)
{
int ret = 0;
@@ -653,20 +610,20 @@ int IsSameLib(library_t* lib, const char* path)
}
int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver)
{
- if(!name[0])
+ if(!lib || !name[0])
return 0;
khint_t k;
+ kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
+ // check first if already in the map
+ k = kh_get(bridgemap, map, VersionedName(name, version, vername));
+ if(k!=kh_end(map)) {
+ *start = kh_value(map, k).start;
+ *end = kh_value(map, k).end;
+ return 1;
+ }
// get a new symbol
if(lib->getweak(lib, name, start, end, size, weak, version, vername, local, defver)) {
*end += *start; // lib->get(...) gives size, not end
- kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
- // check first if already in the map
- k = kh_get(bridgemap, map, VersionedName(name, version, vername));
- if(k!=kh_end(map)) {
- *start = kh_value(map, k).start;
- *end = kh_value(map, k).end;
- return 1;
- }
char* symbol = box_strdup(VersionedName(name, version, vername));
int ret;
k = kh_put(bridgemap, map, symbol, &ret);
@@ -683,17 +640,17 @@ int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* star
if(!name[0] || !lib)
return 0;
khint_t k;
+ kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
+ // check if already in the map
+ k = kh_get(bridgemap, map, VersionedName(name, version, vername));
+ if(k!=kh_end(map)) {
+ *start = kh_value(map, k).start;
+ *end = kh_value(map, k).end;
+ return 1;
+ }
// get a new symbol
if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local, defver)) {
*end += *start; // lib->get(...) gives size, not end
- kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
- // check if already in the map
- k = kh_get(bridgemap, map, VersionedName(name, version, vername));
- if(k!=kh_end(map)) {
- *start = kh_value(map, k).start;
- *end = kh_value(map, k).end;
- return 1;
- }
char* symbol = box_strdup(VersionedName(name, version, vername));
int ret;
k = kh_put(bridgemap, map, symbol, &ret);
@@ -710,16 +667,16 @@ int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start
if(!name[0])
return 0;
khint_t k;
+ // check first if already in the map
+ k = kh_get(bridgemap, lib->lbridgemap, VersionedName(name, version, vername));
+ if(k!=kh_end(lib->lbridgemap)) {
+ *start = kh_value(lib->lbridgemap, k).start;
+ *end = kh_value(lib->lbridgemap, k).end;
+ return 1;
+ }
// get a new symbol
if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local, defver)) {
*end += *start; // lib->get(...) gives size, not end
- // check first if already in the map
- k = kh_get(bridgemap, lib->lbridgemap, VersionedName(name, version, vername));
- if(k!=kh_end(lib->lbridgemap)) {
- *start = kh_value(lib->lbridgemap, k).start;
- *end = kh_value(lib->lbridgemap, k).end;
- return 1;
- }
char* symbol = box_strdup(VersionedName(name, version, vername));
int ret;
k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret);
@@ -799,18 +756,23 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
// check in mysymbolmap
khint_t k = kh_get(symbolmap, lib->w.mysymbolmap, name);
if (k!=kh_end(lib->w.mysymbolmap)) {
- char buff[200];
- if(lib->w.altmy)
- strcpy(buff, lib->w.altmy);
- else
- strcpy(buff, "my_");
- strcat(buff, name);
- symbol = dlsym(my_context->box64lib, buff);
- if(!symbol) {
- printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.mysymbolmap, k), symbol, 0, name);
+ symbol1_t *s = &kh_value(lib->w.mysymbolmap, k);
+ if(!s->resolved) {
+ char buff[200];
+ if(lib->w.altmy)
+ strcpy(buff, lib->w.altmy);
+ else
+ strcpy(buff, "my_");
+ strcat(buff, name);
+ symbol = dlsym(my_context->box64lib, buff);
+ if(!symbol) {
+ printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
+ return 0;
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
+ s->resolved = 1;
+ }
+ *addr = s->addr;
*size = sizeof(void*);
*weak = 0;
return 1;
@@ -818,54 +780,8 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
// check in stsymbolmap (return struct...)
k = kh_get(symbolmap, lib->w.stsymbolmap, name);
if (k!=kh_end(lib->w.stsymbolmap)) {
- char buff[200];
- if(lib->w.altmy)
- strcpy(buff, lib->w.altmy);
- else
- strcpy(buff, "my_");
- strcat(buff, name);
- symbol = dlsym(my_context->box64lib, buff);
- if(!symbol) {
- printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.stsymbolmap, k), symbol, sizeof(void*), name);
- *size = sizeof(void*);
- *weak = 0;
- return 1;
- }
- // check in symbolmap
- k = kh_get(symbolmap, lib->w.symbolmap, name);
- if (k!=kh_end(lib->w.symbolmap)) {
- symbol = dlsym(lib->w.lib, name);
- if(!symbol && lib->w.altprefix) {
- char newname[200];
- strcpy(newname, lib->w.altprefix);
- strcat(newname, name);
- symbol = dlsym(lib->w.lib, newname);
- }
- if(!symbol)
- symbol = GetNativeSymbolUnversioned(lib->w.lib, name);
- if(!symbol && lib->w.altprefix) {
- char newname[200];
- strcpy(newname, lib->w.altprefix);
- strcat(newname, name);
- symbol = GetNativeSymbolUnversioned(lib->w.lib, newname);
- }
- if(!symbol) {
- printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
- return 0;
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbolmap, k), symbol, 0, name);
- *size = sizeof(void*);
- *weak = 0;
- return 1;
- }
- if(!noweak) {
- // check in wmysymbolmap
- khint_t k = kh_get(symbolmap, lib->w.wmysymbolmap, name);
- if (k!=kh_end(lib->w.wmysymbolmap)) {
+ symbol1_t *s = &kh_value(lib->w.stsymbolmap, k);
+ if(!s->resolved) {
char buff[200];
if(lib->w.altmy)
strcpy(buff, lib->w.altmy);
@@ -875,15 +791,21 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
symbol = dlsym(my_context->box64lib, buff);
if(!symbol) {
printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wmysymbolmap, k), symbol, 0, name);
- *size = sizeof(void*);
- *weak = 1;
- return 1;
+ return 0;
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, sizeof(void*), name);
+ s->resolved = 1;
}
- k = kh_get(symbolmap, lib->w.wsymbolmap, name);
- if (k!=kh_end(lib->w.wsymbolmap)) {
+ *addr = s->addr;
+ *size = sizeof(void*);
+ *weak = 0;
+ return 1;
+ }
+ // check in symbolmap
+ k = kh_get(symbolmap, lib->w.symbolmap, name);
+ if (k!=kh_end(lib->w.symbolmap)) {
+ symbol1_t *s = &kh_value(lib->w.symbolmap, k);
+ if(!s->resolved) {
symbol = dlsym(lib->w.lib, name);
if(!symbol && lib->w.altprefix) {
char newname[200];
@@ -900,11 +822,69 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
symbol = GetNativeSymbolUnversioned(lib->w.lib, newname);
}
if(!symbol) {
- printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
+ printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
return 0;
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wsymbolmap, k), symbol, 0, name);
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
+ s->resolved = 1;
+ }
+ *addr = s->addr;
+ *size = sizeof(void*);
+ *weak = 0;
+ return 1;
+ }
+ if(!noweak) {
+ // check in wmysymbolmap
+ khint_t k = kh_get(symbolmap, lib->w.wmysymbolmap, name);
+ if (k!=kh_end(lib->w.wmysymbolmap)) {
+ symbol1_t *s = &kh_value(lib->w.wmysymbolmap, k);
+ if(!s->resolved) {
+ char buff[200];
+ if(lib->w.altmy)
+ strcpy(buff, lib->w.altmy);
+ else
+ strcpy(buff, "my_");
+ strcat(buff, name);
+ symbol = dlsym(my_context->box64lib, buff);
+ if(!symbol) {
+ printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
+ return 0;
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
+ s->resolved = 1;
+ }
+ *addr = s->addr;
+ *size = sizeof(void*);
+ *weak = 1;
+ return 1;
+ }
+ k = kh_get(symbolmap, lib->w.wsymbolmap, name);
+ if (k!=kh_end(lib->w.wsymbolmap)) {
+ symbol1_t *s = &kh_value(lib->w.wsymbolmap, k);
+ if(!s->resolved) {
+ symbol = dlsym(lib->w.lib, name);
+ if(!symbol && lib->w.altprefix) {
+ char newname[200];
+ strcpy(newname, lib->w.altprefix);
+ strcat(newname, name);
+ symbol = dlsym(lib->w.lib, newname);
+ }
+ if(!symbol)
+ symbol = GetNativeSymbolUnversioned(lib->w.lib, name);
+ if(!symbol && lib->w.altprefix) {
+ char newname[200];
+ strcpy(newname, lib->w.altprefix);
+ strcat(newname, name);
+ symbol = GetNativeSymbolUnversioned(lib->w.lib, newname);
+ }
+ if(!symbol) {
+ printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
+ return 0;
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
+ s->resolved = 1;
+ }
+ *addr = s->addr;
*size = sizeof(void*);
*weak = 1;
return 1;
@@ -912,25 +892,29 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
}
// check in symbol2map
k = kh_get(symbol2map, lib->w.symbol2map, name);
- if (k!=kh_end(lib->w.symbol2map))
- if(!noweak || !kh_value(lib->w.symbol2map, k).weak)
+ if (k!=kh_end(lib->w.symbol2map)) {
+ symbol2_t *s = &kh_value(lib->w.symbol2map, k);
+ if(!noweak || !s->weak)
{
- symbol = dlsym(lib->w.lib, kh_value(lib->w.symbol2map, k).name);
- if(!symbol)
- symbol = dlsym(RTLD_DEFAULT, kh_value(lib->w.symbol2map, k).name); // search globaly maybe
- if(!symbol)
- symbol = GetNativeSymbolUnversioned(lib->w.lib, kh_value(lib->w.symbol2map, k).name);
- if(!symbol) {
- printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", kh_value(lib->w.symbol2map, k).name, lib->name);
- return 0;
- } else
- AddOffsetSymbol(my_context->maplib, symbol, name);
- *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbol2map, k).w, symbol, 0, name);
+ if(!s->resolved) {
+ symbol = dlsym(lib->w.lib, kh_value(lib->w.symbol2map, k).name);
+ if(!symbol)
+ symbol = dlsym(RTLD_DEFAULT, kh_value(lib->w.symbol2map, k).name); // search globaly maybe
+ if(!symbol)
+ symbol = GetNativeSymbolUnversioned(lib->w.lib, kh_value(lib->w.symbol2map, k).name);
+ if(!symbol) {
+ printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", kh_value(lib->w.symbol2map, k).name, lib->name);
+ return 0;
+ }
+ s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
+ s->resolved = 1;
+ }
+ *addr = s->addr;
*size = sizeof(void*);
- *weak = kh_value(lib->w.symbol2map, k).weak;
+ *weak = s->weak;
return 1;
}
-
+ }
return 0;
}
@@ -954,7 +938,7 @@ int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *add
int GetNeededLibsN(library_t* lib) {
switch (lib->type) {
case LIB_WRAPPED: return lib->w.needed?lib->w.needed->size:0;
- case LIB_EMULATED: return lib->e.elf->needed->size;
+ case LIB_EMULATED: return lib->e.elf->needed?lib->e.elf->needed->size:0;
}
return 0;
}
@@ -972,11 +956,11 @@ library_t* GetNeededLib(library_t* lib, int idx)
}
return NULL;
}
-char** GetNeededLibs(library_t* lib)
+char** GetNeededLibsNames(library_t* lib)
{
switch (lib->type) {
case LIB_WRAPPED: return lib->w.needed?lib->w.needed->names:NULL;
- case LIB_EMULATED: return lib->e.elf->needed->names;
+ case LIB_EMULATED: return lib->e.elf->needed?lib->e.elf->needed->names:NULL;
}
return NULL;
}
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index 27d3fef..c502306 100644
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -17,13 +17,21 @@ typedef struct x64emu_s x64emu_t;
typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
+typedef struct symbol1_s {
+ wrapper_t w;
+ int resolved;
+ uintptr_t addr;
+} symbol1_t;
+
typedef struct symbol2_s {
wrapper_t w;
const char* name;
int weak;
+ int resolved;
+ uintptr_t addr;
} symbol2_t;
-KHASH_MAP_DECLARE_STR(symbolmap, wrapper_t)
+KHASH_MAP_DECLARE_STR(symbolmap, symbol1_t)
KHASH_MAP_DECLARE_STR(symbol2map, symbol2_t)
KHASH_MAP_DECLARE_STR(datamap, uint64_t)
diff --git a/src/library_list.h b/src/library_list.h
index 9770518..ff08915 100644
--- a/src/library_list.h
+++ b/src/library_list.h
@@ -2,10 +2,10 @@
#error Nope
#endif
-GO("libc.so.6", libc)
GO("libc.musl-x86_64.so.1", libcmusl)
GO("libpthread.so.0", libpthread)
GO("librt.so.1", librt)
+GO("libbsd.so.0", libbsd)
GO("libEGL.so.1", libegl)
GO("libGL.so.1", libgl)
GO("libGL.so", libgl)
@@ -16,8 +16,6 @@ GO("libGLX.so", libglx)
GO("libX11.so.6", libx11)
GO("libasound.so.2", libasound)
GO("libasound.so", libasound)
-GO("libdl.so.2", libdl)
-GO("libm.so.6", libm)
GO("libSDL2-2.0.so.0", sdl2)
GO("libSDL2-2.0.so.1", sdl2)
GO("libSDL2.so", sdl2)
@@ -41,10 +39,10 @@ GO("libvorbis.so.0", libvorbis)
GO("libogg.so.0", libogg)
GO("libFLAC.so.8", flac)
//GO("libpng12.so.0", png12)
-GO("libpng16.so.16", png16)
GO("libXxf86vm.so.1", libxxf86vm)
GO("libXinerama.so.1", xinerama)
GO("libXrandr.so.2", libxrandr)
+GO("libxrandr.so.2", libxrandr)
GO("libXext.so.6", libxext)
GO("libXfixes.so.3", libxfixes)
GO("libXcursor.so.1", libxcursor)
@@ -91,6 +89,7 @@ GO("libopenal.so", openal)
GO("openal.so", openal)
GO("libalut.so.0", alut)
GO("libalure.so.1", alure)
+GO("libOpenCL.so.1", opencl)
//GO("libjpeg.so.8", libjpeg)
//GO("libjpeg.so.62", libjpeg62)
//GO("libturbojpeg.so.0", turbojpeg)
@@ -132,10 +131,11 @@ GO("libgthread-2.0.so.0", gthread2)
//GO("libgstreamer-0.10.so.0", gstreamer010)
//GO("libgstinterfaces-0.10.so.0", gstinterfaces010)
//GO("libdbusmenu-gtk.so.4", dbusmenugtk)
-//GO("libdbusmenu-glib.so.4", dbusmenuglib)
+GO("libdbusmenu-glib.so.4", dbusmenuglib)
GO("libdbus-glib-1.so.2", dbusglib1)
//GO("libgudev-1.0.so.0", gudev1)
//GO("libappindicator.so.1", appindicator)
+GO("libayatana-appindicator3.so.1", ayatanaappindicator3)
GO("libatk-1.0.so.0", atk)
GO("libatk-bridge-2.0.so.0", atkbridge)
GO("libatspi.so.0", atspi)
@@ -152,7 +152,6 @@ GO("libpango-1.0.so", pango)
//GO("libnm-util.so.2", libnm)
GO("libibus-1.0.so.5", libibus)
GO("libfontconfig.so.1", fontconfig)
-GO("libfreetype.so.6", freetype)
GO("libharfbuzz.so.0", libharfbuzz)
GO("libbz2.so.1", bz2)
GO("liblzma.so.5", lzma)
@@ -163,6 +162,7 @@ GO("libncursesw.so.5", libncursesw)
GO("libncursesw.so.6", libncursesw6)
GO("libform.so.5", libform)
GO("libformw.so.5", libformw)
+GO("libformw.so.6", libformw6)
GO("libncurses.so.5", libncurses)
GO("libtinfo.so.5", libtinfo)
GO("libpanel.so.5", libpanel)
@@ -173,26 +173,17 @@ GO("libtbbmalloc_proxy.so.2", tbbmallocproxy)
GO("libtbbbind_2_5.so", tbbbind)
GO("libtcmalloc_minimal.so.0", tcmallocminimal)
GO("libtcmalloc_minimal.so.4", tcmallocminimal)
-GO("libmpg123.so.0", mpg123)
-GO("libgnutls.so.30", gnutls)
GO("libpcre.so.3", libpcre)
-GO("libcups.so.2", libcups)
GO("libvulkan.so.1", vulkan)
GO("libvulkan.so", vulkan)
//GO("libwayland-client.so.0", waylandclient)
GO("libgbm.so.1", gbm)
-GO("libxml2.so.2", xml2)
-GO("libxslt.so.1", xslt)
GO("libgomp.so.1", gomp)
GO("libcap.so.2", cap)
-GO("libldap_r-2.4.so.2", ldapr)
-GO("liblber-2.4.so.2", lber)
//GO("libnsl.so.1", nsl)
-//GO("liblcms2.so.2", lcms2)
GO("libkrb5.so.3", krb5)
GO("libgssapi_krb5.so.2", gssapikrb5)
GO("libgssapi.so.3", gssapi)
-//GO("libtiff.so.5", libtiff)
GO("libfuse.so.2", libfuse)
GO("libnss3.so", nss3)
GO("libnssutil3.so", nssutil3)
@@ -208,15 +199,27 @@ GO("libsecret-1.so.0", secret1)
GO("libpci.so.3", libpci)
GO("libgmp.so.10", gmp)
GO("libFAudio.so.0", faudio)
+GO("libgstallocators-1.0.so.0", gstallocators)
GO("libgstapp-1.0.so.0", gstapp)
GO("libgstaudio-1.0.so.0", gstaudio)
GO("libgstbase-1.0.so.0", gstbase)
+GO("libgstcheck-1.0.so.0", gstcheck)
+GO("libgstcontroller-1.0.so.0", gstcontroller)
+GO("libgstfft-1.0.so.0", gstfft)
GO("libgstgl-1.0.so.0", gstgl)
+GO("libgstnet-1.0.so.0", gstnet)
+GO("libgstpbutils-1.0.so.0", gstpbutils)
GO("libgstreamer-1.0.so.0", gstreamer)
+GO("libgstriff-1.0.so.0", gstriff)
+GO("libgstrtp-1.0.so.0", gstrtp)
+GO("libgstrtsp-1.0.so.0", gstrtsp)
+GO("libgstsdp-1.0.so.0", gstsdp)
GO("libgsttag-1.0.so.0", gsttag)
GO("libgstvideo-1.0.so.0", gstvideo)
GO("libxshmfence.so.1", xshmfence)
GO("libatomic.so.1", atomic)
+GO("liblcms2.so.2", lcms2)
+GO("libevent-2.1.so.7", event21)
GO("libsoftokn3.so", softokn3)
GO("libwayland-egl.so.1", waylandegl)
GO("libwayland-client.so.0", waylandclient)
@@ -229,12 +232,127 @@ GO("libvdpau.so.1", libvdpau)
GO("libnuma.so.1", libnuma)
GO("libnuma.so", libnuma)
GO("d3dadapter9.so.1", d3dadapter9)
+GO("libicuuc.so.66", icuuc66)
+GO("libicui18n.so.66", icui18n66)
GO("libicuuc.so.67", icuuc67)
GO("libicui18n.so.67", icui18n67)
GO("libicuuc.so.72", icuuc72)
GO("libicui18n.so.72", icui18n72)
+#ifdef ANDROID
+GO("libc.so", libc)
+GO("libm.so", libm)
+GO("libbsd.so", libbsd)
+GO("libdl.so", libdl)
+GO("libcups.so", libcups)
+GO("liblber-2.4.so", lber)
+GO("libldap_r-2.4.so", ldapr)
+GO("libpng16.so", png16)
+GO("libxslt.so", xslt)
+GO("libfreetype.so", freetype)
+GO("libgnutls.so", gnutls)
+//GO("liblcms2.so", lcms2)
+GO("libmpg123.so", mpg123)
+//GO("libtiff.so", libtiff)
+GO("libxml2.so", xml2)
+GO("libX11.so", libx11)
+GO("libXext.so", libxext)
+GO("libxcb.so", libxcb)
+GO("libXau.so", libxau)
+GO("libXxf86vm.so", libxxf86vm)
+GO("libXinerama.so", xinerama)
+GO("libXrandr.so", libxrandr)
+GO("libxrandr.so", libxrandr)
+GO("libXext.so", libxext)
+GO("libXfixes.so", libxfixes)
+GO("libXcursor.so", libxcursor)
+GO("libXrender.so", libxrender)
+GO("libXft.so", libxft)
+GO("libXi.so", libxi)
+GO("libXss.so", libxss)
+GO("libXpm.so", libxpm)
+GO("libXau.so", libxau)
+GO("libXdmcp.so", libxdmcp)
+GO("libX11-xcb.so", libx11xcb)
+GO("libxcb.so", libxcb)
+GO("libxcb-xfixes.so", libxcbxfixes)
+GO("libxcb-shape.so", libxcbshape)
+GO("libxcb-shm.so", libxcbshm)
+GO("libxcb-randr.so", libxcbrandr)
+GO("libxcb-present.so", libxcbpresent)
+GO("libxcb-image.so", libxcbimage)
+GO("libxcb-keysyms.so", libxcbkeysyms)
+GO("libxcb-xtest.so", libxcbxtest)
+GO("libxcb-glx.so", libxcbglx)
+GO("libxcb-dri2.so", libxcbdri2)
+GO("libxcb-dri3.so", libxcbdri3)
+GO("libxcb-icccm.so", libxcbicccm)
+GO("libxcb-util.so", libxcbutil)
+GO("libxcb-render-util.so", libxcbrenderutil)
+GO("libxcb-render.so", libxcbrender)
+GO("libxcb-sync.so", libxcbsync)
+GO("libxcb-xinerama.so", libxcbxinerama)
+GO("libxcb-xkb.so", libxcbxkb)
+//GO("libxcb-present.so", libxcbpresent)
+GO("libXtst.so", libxtst)
+GO("libXt.so", libxt)
+GO("libXcomposite.so", libxcomposite)
+GO("libXdamage.so", libxdamage)
+GO("libXpresent.so", libxpresent)
+GO("libXmu.so", libxmu)
+GO("libxkbcommon.so", xkbcommon)
+GO("libxkbcommon-x11.so", xkbcommonx11)
+GO("libpulse-simple.so", pulsesimple)
+GO("libpulse.so", pulse)
+GO("libsndfile.so", libsndfile)
+GO("libgstallocators-1.0.so", gstallocators)
+GO("libgstapp-1.0.so", gstapp)
+GO("libgstaudio-1.0.so", gstaudio)
+GO("libgstbase-1.0.so", gstbase)
+GO("libgstcheck-1.0.so", gstcheck)
+GO("libgstcontroller-1.0.so", gstcontroller)
+GO("libgstfft-1.0.so", gstfft)
+GO("libgstgl-1.0.so", gstgl)
+GO("libgstnet-1.0.so", gstnet)
+GO("libgstpbutils-1.0.so", gstpbutils)
+GO("libgstreamer-1.0.so", gstreamer)
+GO("libgstriff-1.0.so", gstriff)
+GO("libgstrtp-1.0.so", gstrtp)
+GO("libgstrtsp-1.0.so", gstrtsp)
+GO("libgstsdp-1.0.so", gstsdp)
+GO("libgsttag-1.0.so", gsttag)
+GO("libgstvideo-1.0.so", gstvideo)
+GO("libxshmfence.so", xshmfence)
+GO("libusb-1.0.so", libusb1)
+GO("libvorbisfile.so", vorbisfile)
+GO("libvorbis.so", libvorbis)
+GO("libogg.so", libogg)
+GO("libFLAC.so", flac)
+GO("libz.so", libz)
+GO("libandroid-shmem.so", androidshmem)
+#else
+GO("libc.so.6", libc)
+GO("libm.so.6", libm)
+GO("libdl.so.2", libdl)
+GO("libcups.so.2", libcups)
+GO("liblber-2.4.so.2", lber)
+GO("libldap_r-2.4.so.2", ldapr)
+GO("libpng16.so.16", png16)
+GO("libxslt.so.1", xslt)
+GO("libfreetype.so.6", freetype)
+GO("libgnutls.so.30", gnutls)
+//GO("liblcms2.so.2", lcms2)
+GO("libmpg123.so.0", mpg123)
+//GO("libtiff.so.5", libtiff)
+GO("libxml2.so.2", xml2)
+#endif
+#ifdef TERMUX
+GO("libiconv.so", iconv)
+GO("libtermux-exec.so", termuxexec)
+GO("libandroid-support.so", androidsupport)
+#endif
+
GO("ld-linux-x86-64.so.2", ldlinux)
-GO("libunwind.so.8", unwind)
+//GO("libunwind.so.8", unwind)
GO("crashhandler.so", crashhandler)
diff --git a/src/libtools/myalign.c b/src/libtools/myalign.c
index 36873cb..6cb96ab 100644
--- a/src/libtools/myalign.c
+++ b/src/libtools/myalign.c
@@ -13,7 +13,7 @@
#include "myalign.h"
#include "debug.h"
-static int regs_abi[] = {_DI, _SI, _DX, _CX, _R8, _R9};
+static const int regs_abi[] = {_DI, _SI, _DX, _CX, _R8, _R9};
void myStackAlign(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos)
{
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index e47a3da..e5d0d7e 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -13,7 +13,9 @@
#include <setjmp.h>
#include <sys/mman.h>
#include <pthread.h>
+#ifndef ANDROID
#include <execinfo.h>
+#endif
#include "box64context.h"
#include "debug.h"
@@ -290,6 +292,11 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext,
trace_start = 0; trace_end = 1; // disabling trace, globably for now...
#endif
#endif
+#ifndef USE_CUSTOM_MEM
+ // because a signal can interupt a malloc-like function
+ // Dynarec cannot be used in signal handling unless custom malloc is used
+ dynarec = 0;
+#endif
x64emu_t *emu = thread_get_emu();
#ifdef DYNAREC
@@ -539,13 +546,256 @@ void copyUCTXreg2Emu(x64emu_t* emu, ucontext_t* p, uintptr_t ip) {
emu->regs[_R14].q[0] = p->uc_mcontext.__gregs[30];
emu->regs[_R15].q[0] = p->uc_mcontext.__gregs[31];
emu->ip.q[0] = ip;
- emu->eflags.x64 = p->uc_mcontext.__gregs[5];
+ emu->eflags.x64 = p->uc_mcontext.__gregs[8];
#else
#error Unsupported architecture
#endif
#endif
}
+int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd)
+{
+ if((uintptr_t)pc<0x10000)
+ return 0;
+#ifdef ARM64
+ ucontext_t *p = (ucontext_t *)ucntx;
+ uint32_t opcode = *(uint32_t*)pc;
+ struct fpsimd_context *fpsimd = (struct fpsimd_context *)_fpsimd;
+ //printf_log(LOG_INFO, "Checking SIGBUS special casses with pc=%p, opcode=%x, fpsimd=%p\n", pc, opcode, fpsimd);
+ if((opcode&0b10111111110000000000000000000000)==0b10111001000000000000000000000000) {
+ // this is STR
+ int scale = (opcode>>30)&3;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint64_t offset = (opcode>>10)&0b111111111111;
+ offset<<=scale;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = p->uc_mcontext.regs[val];
+ if(scale==3 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<2; ++i)
+ ((uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff;
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b10111111111000000000110000000000) == 0b10111000000000000000000000000000) {
+ // this is a STUR that SIGBUS if accessing unaligned device memory
+ int size = 1<<((opcode>>30)&3);
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ int64_t offset = (opcode>>12)&0b111111111;
+ if((offset>>(9-1))&1)
+ offset |= (0xffffffffffffffffll<<9);
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = p->uc_mcontext.regs[val];
+ if(size==8 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<2; ++i)
+ ((uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff;
+ } else
+ for(int i=0; i<size; ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b00111111010000000000000000000000)==0b00111101000000000000000000000000) {
+ // this is VSTR
+ int scale = (opcode>>30)&3;
+ if((opcode>>23)&1)
+ scale+=4;
+ if(scale>4)
+ return 0;
+ if(!fpsimd)
+ return 0;
+ uint64_t offset = (opcode>>10)&0b111111111111;
+ offset<<=scale;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ __uint128_t value = fpsimd->vregs[val];
+ if(scale>2 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<(1<<(scale-2)); ++i)
+ ((uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff;
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b00111111011000000000110000000000)==0b00111100000000000000000000000000) {
+ // this is VSTRU
+ int scale = (opcode>>30)&3;
+ if((opcode>>23)&1)
+ scale+=4;
+ if(scale>4)
+ return 0;
+ if(!fpsimd)
+ return 0;
+ int64_t offset = (opcode>>12)&0b111111111;
+ if((offset>>(9-1))&1)
+ offset |= (0xffffffffffffffffll<<9);
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ __uint128_t value = fpsimd->vregs[val];
+ if(scale>2 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<(1<<(scale-2)); ++i)
+ ((uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff;
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b00111111010000000000000000000000)==0b00111101010000000000000000000000) {
+ // this is VLDR
+ int scale = (opcode>>30)&3;
+ if((opcode>>23)&1)
+ scale+=4;
+ if(scale>4)
+ return 0;
+ if(!fpsimd)
+ return 0;
+ uint64_t offset = (opcode>>10)&0b111111111111;
+ offset<<=scale;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ __uint128_t value = 0;
+ if(scale>2 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<(1<<(scale-2)); ++i)
+ value |= ((__uint128_t)(((uint32_t*)addr)[i]))<<(i*32);
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ value |= ((__uint128_t)addr[i])<<(i*8);
+ fpsimd->vregs[val] = value;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b00111111011000000000110000000000)==0b00111100010000000000000000000000) {
+ // this is VLDRU
+ int scale = (opcode>>30)&3;
+ if((opcode>>23)&1)
+ scale+=4;
+ if(scale>4)
+ return 0;
+ if(!fpsimd)
+ return 0;
+ int64_t offset = (opcode>>12)&0b111111111;
+ if((offset>>(9-1))&1)
+ offset |= (0xffffffffffffffffll<<9);
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ __uint128_t value = 0;
+ if(scale>2 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<(1<<(scale-2)); ++i)
+ value |= ((__uint128_t)(((uint32_t*)addr)[i]))<<(i*32);
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ value |= ((__uint128_t)addr[i])<<(i*8);
+ fpsimd->vregs[val] = value;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b10111111110000000000000000000000)==0b10111001010000000000000000000000) {
+ // this is LDR
+ int scale = (opcode>>30)&3;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint64_t offset = (opcode>>10)&0b111111111111;
+ offset<<=scale;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = 0;
+ if(scale==3 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<2; ++i)
+ value |= ((uint64_t)((uint32_t*)addr)[i]) << (i*32);
+ } else
+ for(int i=0; i<(1<<scale); ++i)
+ value |= ((uint64_t)addr[i]) << (i*8);
+ p->uc_mcontext.regs[val] = value;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b10111111111000000000110000000000) == 0b10111000010000000000000000000000) {
+ // this is a LDUR
+ int size = 1<<((opcode>>30)&3);
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ int64_t offset = (opcode>>12)&0b111111111;
+ if((offset>>(9-1))&1)
+ offset |= (0xffffffffffffffffll<<9);
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = 0;
+ if(size==8 && ((uintptr_t)addr)&3==0) {
+ for(int i=0; i<2; ++i)
+ value |= ((uint64_t)((uint32_t*)addr)[i]) << (i*32);
+ } else
+ for(int i=0; i<size; ++i)
+ value |= ((uint64_t)addr[i]) << (i*8);
+ p->uc_mcontext.regs[val] = value;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b11111111110000000000000000000000)==0b01111001000000000000000000000000) {
+ // this is STRH
+ int scale = (opcode>>30)&3;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ uint64_t offset = (opcode>>10)&0b111111111111;
+ offset<<=scale;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = p->uc_mcontext.regs[val];
+ for(int i=0; i<(1<<scale); ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b11111111111000000000110000000000)==0b01111000001000000000100000000000) {
+ // this is STRH reg, reg
+ int scale = (opcode>>30)&3;
+ int val = opcode&31;
+ int dest = (opcode>>5)&31;
+ int dest2 = (opcode>>16)&31;
+ int option = (opcode>>13)&0b111;
+ int S = (opcode>>12)&1;
+ if(option!=0b011)
+ return 0; // only LSL is supported
+ uint64_t offset = p->uc_mcontext.regs[dest2]<<S;
+ uint8_t* addr = (uint8_t*)(p->uc_mcontext.regs[dest] + offset);
+ uint64_t value = p->uc_mcontext.regs[val];
+ for(int i=0; i<(1<<scale); ++i)
+ addr[i] = (value>>(i*8))&0xff;
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+ if((opcode&0b11111111110000000000000000000000)==0b10101001000000000000000000000000) {
+ // This is STP reg1, reg2, [reg3 + off]
+ int scale = 2+(opcode>>31)&1;
+ int val1 = opcode&31;
+ int val2 = (opcode>>10)&31;
+ int dest = (opcode>>5)&31;
+ int64_t offset = (opcode>>15)&0b1111111;
+ if((offset>>(7-1))&1)
+ offset |= (0xffffffffffffffffll<<7);
+ offset <<= scale;
+ uintptr_t addr= p->uc_mcontext.regs[dest] + offset;
+ if(((uintptr_t)addr)&3==0) {
+ ((uint32_t*)addr)[0] = p->uc_mcontext.regs[val1];
+ ((uint32_t*)addr)[1] = p->uc_mcontext.regs[val2];
+ } else {
+ __uint128_t value = ((__uint128_t)p->uc_mcontext.regs[val2])<<64 | p->uc_mcontext.regs[val1];
+ for(int i=0; i<(1<<scale); ++i)
+ ((uint8_t*)addr)[i] = (value>>(i*8))&0xff;
+ }
+ p->uc_mcontext.pc+=4; // go to next opcode
+ return 1;
+ }
+#endif
+ return 0;
+}
+
void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
{
int Locks = unlockMutex();
@@ -558,25 +808,31 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
uintptr_t frame = R_RSP;
#if defined(DYNAREC)
#if defined(ARM64)
- ucontext_t *p = (ucontext_t *)ucntx;
- void * pc = (void*)p->uc_mcontext.pc;
dynablock_t* db = (dynablock_t*)cur_db;//FindDynablockFromNativeAddress(pc);
- if(db) {
- frame = (uintptr_t)p->uc_mcontext.regs[10+_SP];
+ ucontext_t *p = (ucontext_t *)ucntx;
+ void* pc = NULL;
+ if(p) {
+ pc = (void*)p->uc_mcontext.pc;
+ if(db)
+ frame = (uintptr_t)p->uc_mcontext.regs[10+_SP];
}
#elif defined(LA464)
- ucontext_t *p = (ucontext_t *)ucntx;
- void * pc = (void*)p->uc_mcontext.__pc;
dynablock_t* db = (dynablock_t*)cur_db;//FindDynablockFromNativeAddress(pc);
- if(db) {
- frame = (uintptr_t)p->uc_mcontext.__gregs[12+_SP];
+ ucontext_t *p = (ucontext_t *)ucntx;
+ void* pc = NULL;
+ if(p) {
+ pc = (void*)p->uc_mcontext.__pc;
+ if(db)
+ frame = (uintptr_t)p->uc_mcontext.__gregs[12+_SP];
}
#elif defined(RV64)
- ucontext_t *p = (ucontext_t *)ucntx;
- void * pc = (void*)p->uc_mcontext.__gregs[0];
dynablock_t* db = (dynablock_t*)cur_db;//FindDynablockFromNativeAddress(pc);
- if(db) {
- frame = (uintptr_t)p->uc_mcontext.__gregs[16+_SP];
+ ucontext_t *p = (ucontext_t *)ucntx;
+ void* pc = NULL;
+ if(p) {
+ pc = (void*)p->uc_mcontext.__gregs[0];
+ if(db)
+ frame = (uintptr_t)p->uc_mcontext.__gregs[16+_SP];
}
#else
#error Unsupported architecture
@@ -634,7 +890,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
sigcontext->uc_mcontext.gregs[X64_CSGSFS] = ((uint64_t)(R_CS)) | (((uint64_t)(R_GS))<<16) | (((uint64_t)(R_FS))<<32);
#if defined(DYNAREC)
#if defined(ARM64)
- if(db) {
+ if(db && p) {
sigcontext->uc_mcontext.gregs[X64_RAX] = p->uc_mcontext.regs[10];
sigcontext->uc_mcontext.gregs[X64_RCX] = p->uc_mcontext.regs[11];
sigcontext->uc_mcontext.gregs[X64_RDX] = p->uc_mcontext.regs[12];
@@ -654,7 +910,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
sigcontext->uc_mcontext.gregs[X64_RIP] = getX64Address(db, (uintptr_t)pc);
}
#elif defined(LA464)
- if(db) {
+ if(db && p) {
sigcontext->uc_mcontext.gregs[X64_RAX] = p->uc_mcontext.__gregs[12];
sigcontext->uc_mcontext.gregs[X64_RCX] = p->uc_mcontext.__gregs[13];
sigcontext->uc_mcontext.gregs[X64_RDX] = p->uc_mcontext.__gregs[14];
@@ -674,7 +930,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
sigcontext->uc_mcontext.gregs[X64_RIP] = getX64Address(db, (uintptr_t)pc);
}
#elif defined(RV64)
- if(db) {
+ if(db && p) {
sigcontext->uc_mcontext.gregs[X64_RAX] = p->uc_mcontext.__gregs[16];
sigcontext->uc_mcontext.gregs[X64_RCX] = p->uc_mcontext.__gregs[17];
sigcontext->uc_mcontext.gregs[X64_RDX] = p->uc_mcontext.__gregs[18];
@@ -738,20 +994,48 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
else if(sig==SIGSEGV) {
if((uintptr_t)info->si_addr == sigcontext->uc_mcontext.gregs[X64_RIP]) {
sigcontext->uc_mcontext.gregs[X64_ERR] = (info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010); // execution flag issue (probably), unless it's a #GP(0)
- sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR || (info->si_errno==0x1234) || (info->si_errno==0xdead) || (uintptr_t)info->si_addr==0)?13:14;
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14;
} else if(info->si_code==SEGV_ACCERR && !(prot&PROT_WRITE)) {
sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0002; // write flag issue
if(labs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[X64_RSP])<16)
sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 12; // stack overflow probably
else
- sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14; // PAGE_FAULT
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14;
} else {
- sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?13:14;
//X64_ERR seems to be INT:8 CODE:8. So for write access segfault it's 0x0002 For a read it's 0x0004 (and 8 for exec). For an int 2d it could be 0x2D01 for example
sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0004; // read error? there is no execute control in box64 anyway
}
if(info->si_code == SEGV_ACCERR && old_code)
*old_code = -1;
+ if(info->si_errno==0x1234) {
+ info2->si_errno = 0;
+ } else if(info->si_errno==0xdead) {
+ // INT x
+ uint8_t int_n = info2->si_code;
+ info2->si_errno = 0;
+ info2->si_code = info->si_code;
+ info2->si_addr = NULL;
+ // some special cases...
+ if(int_n==3) {
+ info2->si_signo = SIGTRAP;
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 3;
+ sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
+ sigcontext->uc_mcontext.gregs[X64_RIP]+=2; // segfault after the INT
+ } else if(int_n==0x04) {
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 4;
+ sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
+ sigcontext->uc_mcontext.gregs[X64_RIP]+=2; // segfault after the INT
+ } else if (int_n==0x29 || int_n==0x2c || int_n==0x2d) {
+ sigcontext->uc_mcontext.gregs[X64_ERR] = 0x02|(int_n<<3);
+ } else {
+ sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0a|(int_n<<3);
+ }
+ } else if(info->si_errno==0xcafe) {
+ info2->si_errno = 0;
+ sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 0;
+ info2->si_signo = SIGFPE;
+ }
} else if(sig==SIGFPE) {
if (info->si_code == FPE_INTOVF)
sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 4;
@@ -787,10 +1071,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
if(sig!=SIGSEGV && !(Locks&is_dyndump_locked))
dynarec = 1;
#endif
- /*if (simple)
- ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[sig], 1, sig);
- else*/
- ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[sig], 3, sig, info2, sigcontext);
+ ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[info2->si_signo], 3, info2->si_signo, info2, sigcontext);
// restore old value from emu
if(used_stack) // release stack
new_ss->ss_flags = 0;
@@ -853,7 +1134,11 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
if(Locks & is_dyndump_locked)
CancelBlock64(1);
#endif
+ #ifdef ANDROID
+ siglongjmp(*emu->jmpbuf, 1);
+ #else
siglongjmp(emu->jmpbuf, 1);
+ #endif
}
printf_log(LOG_INFO, "Warning, context has been changed in Sigactionhanlder%s\n", (sigcontext->uc_mcontext.gregs[X64_RIP]!=sigcontext_copy.uc_mcontext.gregs[X64_RIP])?" (EIP changed)":"");
}
@@ -922,7 +1207,16 @@ extern int box64_quit;
void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
{
// sig==SIGSEGV || sig==SIGBUS || sig==SIGILL || sig==SIGABRT here!
- int log_minimum = (box64_showsegv)?LOG_NONE:((my_context->is_sigaction[sig] && sig==SIGSEGV)?LOG_DEBUG:LOG_INFO);
+ int log_minimum = (box64_showsegv)?LOG_NONE:((sig==SIGSEGV && my_context->is_sigaction[sig])?LOG_DEBUG:LOG_INFO);
+ JUMPBUFF signal_jmpbuf;
+ #ifdef ANDROID
+ #define SIG_JMPBUF signal_jmpbuf
+ #else
+ #define SIG_JMPBUF &signal_jmpbuf
+ #endif
+ int signal_jmpbuf_active = 0;
+ if(signal_jmpbuf_active)
+ longjmp(SIG_JMPBUF, 1);
if((sig==SIGSEGV || sig==SIGBUS) && box64_quit) {
printf_log(LOG_INFO, "Sigfault/Segbus while quitting, exiting silently\n");
exit(0); // Hack, segfault while quiting, exit silently
@@ -946,18 +1240,29 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
}
#elif defined __x86_64__
void * pc = (void*)p->uc_mcontext.gregs[X64_RIP];
+ void* fpsimd = NULL;
#elif defined __powerpc64__
void * pc = (void*)p->uc_mcontext.gp_regs[PT_NIP];
+ void* fpsimd = NULL;
#elif defined(LA464)
void * pc = (void*)p->uc_mcontext.__pc;
+ void* fpsimd = NULL;
#elif defined(SW64)
void * pc = (void*)p->uc_mcontext.sc_pc;
+ void* fpsimd = NULL;
#elif defined(RV64)
void * pc = (void*)p->uc_mcontext.__gregs[REG_PC];
+ void* fpsimd = NULL;
#else
void * pc = NULL; // unknow arch...
+ void* fpsimd = NULL;
#warning Unhandled architecture
#endif
+ if((sig==SIGBUS) && (addr!=pc) && sigbus_specialcases(info, ucntx, pc, fpsimd)) {
+ // special case fixed, restore everything and just continues
+ printf_log(LOG_DEBUG, "Special unalinged cased fixed, continue");
+ return;
+ }
int Locks = unlockMutex();
uint32_t prot = getProtection((uintptr_t)addr);
#ifdef BAD_SIGNAL
@@ -969,11 +1274,12 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
}
#endif
#ifdef DYNAREC
- if((Locks & is_dyndump_locked) && (sig==SIGSEGV) && current_helper) {
- printf_log(LOG_INFO, "FillBlock triggered a segfault at %p from %p\n", addr, pc);
+ if((Locks & is_dyndump_locked) && ((sig==SIGSEGV) || (sig==SIGBUS)) && current_helper) {
+ printf_log(LOG_INFO, "FillBlock triggered a %s at %p from %p\n", (sig==SIGSEGV)?"segfault":"bus error", addr, pc);
CancelBlock64(0);
- cancelFillBlock(); // Segfault inside a Fillblock, cancel it's creation...
relockMutex(Locks);
+ cancelFillBlock(); // Segfault inside a Fillblock, cancel it's creation...
+ // cancelFillBlock does not return
}
dynablock_t* db = NULL;
int db_searched = 0;
@@ -1036,7 +1342,11 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
if(Locks & is_dyndump_locked)
CancelBlock64(1);
emu->test.clean = 0;
+ #ifdef ANDROID
+ siglongjmp(*(JUMPBUFF*)emu->jmpbuf, 2);
+ #else
siglongjmp(emu->jmpbuf, 2);
+ #endif
}
dynarec_log(LOG_INFO, "Warning, Auto-SMC (%p for db %p/%p) detected, but jmpbuffer not ready!\n", (void*)addr, db, (void*)db->x64_addr);
}
@@ -1111,21 +1421,26 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
static void* old_pc = 0;
static void* old_addr = 0;
static int old_tid = 0;
+ static int old_prot = 0;
+ int tid = GetTID();
+ int mapped = getMmapped((uintptr_t)addr);
const char* signame = (sig==SIGSEGV)?"SIGSEGV":((sig==SIGBUS)?"SIGBUS":((sig==SIGILL)?"SIGILL":"SIGABRT"));
- if(old_code==info->si_code && old_pc==pc && old_addr==addr && old_tid==GetTID()) {
- printf_log(log_minimum, "%04d|Double %s (code=%d, pc=%p, addr=%p)!\n", GetTID(), signame, old_code, old_pc, old_addr);
+ if(old_code==info->si_code && old_pc==pc && old_addr==addr && old_tid==tid && old_prot==prot) {
+ printf_log(log_minimum, "%04d|Double %s (code=%d, pc=%p, addr=%p, prot=%02x)!\n", tid, signame, old_code, old_pc, old_addr, prot);
exit(-1);
} else {
if((sig==SIGSEGV) && (info->si_code == SEGV_ACCERR) && ((prot&~PROT_CUSTOM)==5 || (prot&~PROT_CUSTOM)==7)) {
static uintptr_t old_addr = 0;
- printf_log(/*LOG_DEBUG*/LOG_INFO, "Strange SIGSEGV with Access error on %p for %p, db=%p, prot=0x%x (old_addr=%p)\n", pc, addr, db, prot, (void*)old_addr);
+ printf_log(/*LOG_DEBUG*/LOG_INFO, "%04d| Strange SIGSEGV with Access error on %p for %p%s, db=%p, prot=0x%x (old_addr=%p)\n", tid, pc, addr, mapped?" mapped":"", db, prot, (void*)old_addr);
#ifdef DYNAREC
cleanDBFromAddressRange(((uintptr_t)addr)&~(box64_pagesize-1), box64_pagesize, 0);
#endif
- if(old_addr!=(uintptr_t)addr || getMmapped((uintptr_t)addr)) {
+ if(!(old_addr==(uintptr_t)addr && old_prot==prot) || mapped) {
old_addr = (uintptr_t)addr;
+ old_prot = prot;
refreshProtection(old_addr);
relockMutex(Locks);
+ sched_yield(); // give time to the other process
return; // that's probably just a multi-task glitch, like seen in terraria
}
old_addr = 0;
@@ -1133,7 +1448,8 @@ exit(-1);
old_code = info->si_code;
old_pc = pc;
old_addr = addr;
- old_tid = GetTID();
+ old_tid = tid;
+ old_prot = prot;
const char* name = (log_minimum<=box64_log)?GetNativeName(pc):NULL;
uintptr_t x64pc = (uintptr_t)-1;
const char* x64name = NULL;
@@ -1172,7 +1488,12 @@ exit(-1);
if(!db && (sig==SIGSEGV) && ((uintptr_t)addr==x64pc-1))
x64pc--;
if(log_minimum<=box64_log) {
- x64name = getAddrFunctionName(x64pc);
+ signal_jmpbuf_active = 1;
+ if(sigsetjmp(SIG_JMPBUF, 1)) {
+ // segfault while gathering function name...
+ } else
+ x64name = getAddrFunctionName(x64pc);
+ signal_jmpbuf_active = 0;
elfheader_t* elf = FindElfAddress(my_context, x64pc);
if(elf)
elfname = ElfName(elf);
@@ -1195,12 +1516,15 @@ exit(-1);
sprintf(myarg, "%d", pid);
if(jit_gdb==2)
execlp("gdbserver", "gdbserver", "127.0.0.1:1234", "--attach", myarg, (char*)NULL);
+ else if(jit_gdb==3)
+ execlp("lldb", "lldb", "-p", myarg, (char*)NULL);
else
execlp("gdb", "gdb", "-pid", myarg, (char*)NULL);
exit(-1);
}
}
print_cycle_log(log_minimum);
+#ifndef ANDROID
if((box64_showbt || sig==SIGABRT) && log_minimum<=box64_log) {
// show native bt
#define BT_BUF_SIZE 100
@@ -1269,6 +1593,7 @@ exit(-1);
GO(RIP);
#undef GO
}
+#endif
if(log_minimum<=box64_log) {
static const char* reg_name[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", " R8", " R9","R10","R11", "R12","R13","R14","R15"};
static const char* seg_name[] = {"ES", "CS", "SS", "DS", "FS", "GS"};
@@ -1331,12 +1656,13 @@ exit(-1);
for (int i=0; i<6; ++i)
printf_log(log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
}
- if(sig==SIGILL)
+ if(sig==SIGILL) {
printf_log(log_minimum, " opcode=%02X %02X %02X %02X %02X %02X %02X %02X (%02X %02X %02X %02X %02X)\n", ((uint8_t*)pc)[0], ((uint8_t*)pc)[1], ((uint8_t*)pc)[2], ((uint8_t*)pc)[3], ((uint8_t*)pc)[4], ((uint8_t*)pc)[5], ((uint8_t*)pc)[6], ((uint8_t*)pc)[7], ((uint8_t*)x64pc)[0], ((uint8_t*)x64pc)[1], ((uint8_t*)x64pc)[2], ((uint8_t*)x64pc)[3], ((uint8_t*)x64pc)[4]);
- else if(sig==SIGBUS)
- printf_log(log_minimum, " x86opcode=%02X %02X %02X %02X %02X %02X %02X %02X\n", ((uint8_t*)x64pc)[0], ((uint8_t*)x64pc)[1], ((uint8_t*)x64pc)[2], ((uint8_t*)x64pc)[3], ((uint8_t*)x64pc)[4], ((uint8_t*)x64pc)[5], ((uint8_t*)x64pc)[6], ((uint8_t*)x64pc)[7]);
- else
+ } else if(sig==SIGBUS) {
+ printf_log(log_minimum, " x86opcode=%02X %02X %02X %02X %02X %02X %02X %02X (opcode=%08x)\n", ((uint8_t*)x64pc)[0], ((uint8_t*)x64pc)[1], ((uint8_t*)x64pc)[2], ((uint8_t*)x64pc)[3], ((uint8_t*)x64pc)[4], ((uint8_t*)x64pc)[5], ((uint8_t*)x64pc)[6], ((uint8_t*)x64pc)[7], *(uint32_t*)pc);
+ } else {
printf_log(log_minimum, "\n");
+ }
}
}
relockMutex(Locks);
@@ -1372,9 +1698,12 @@ void my_sigactionhandler(int32_t sig, siginfo_t* info, void * ucntx)
my_sigactionhandler_oldcode(sig, 0, info, ucntx, NULL, db);
}
+#ifndef DYNAREC
+#define box64_dynarec_dump 0
+#endif
+
void emit_signal(x64emu_t* emu, int sig, void* addr, int code)
{
- ucontext_t ctx = {0};
siginfo_t info = {0};
info.si_signo = sig;
info.si_errno = (sig==SIGSEGV)?0x1234:0; // Mark as a sign this is a #GP(0) (like privileged instruction)
@@ -1382,19 +1711,18 @@ void emit_signal(x64emu_t* emu, int sig, void* addr, int code)
info.si_addr = addr;
const char* x64name = NULL;
const char* elfname = NULL;
- if(box64_log>LOG_INFO) {
+ if(box64_log>LOG_INFO || box64_dynarec_dump || box64_showsegv) {
x64name = getAddrFunctionName(R_RIP);
elfheader_t* elf = FindElfAddress(my_context, R_RIP);
if(elf)
elfname = ElfName(elf);
printf_log(LOG_NONE, "Emit Signal %d at IP=%p(%s / %s) / addr=%p, code=%d\n", sig, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr, code);
}
- my_sigactionhandler_oldcode(sig, 0, &info, &ctx, NULL, NULL);
+ my_sigactionhandler_oldcode(sig, 0, &info, NULL, NULL, NULL);
}
void emit_interruption(x64emu_t* emu, int num, void* addr)
{
- ucontext_t ctx = {0};
siginfo_t info = {0};
info.si_signo = SIGSEGV;
info.si_errno = 0xdead;
@@ -1402,19 +1730,38 @@ void emit_interruption(x64emu_t* emu, int num, void* addr)
info.si_addr = addr;
const char* x64name = NULL;
const char* elfname = NULL;
- if(box64_log>LOG_INFO) {
+ if(box64_log>LOG_INFO || box64_dynarec_dump || box64_showsegv) {
x64name = getAddrFunctionName(R_RIP);
elfheader_t* elf = FindElfAddress(my_context, R_RIP);
if(elf)
elfname = ElfName(elf);
printf_log(LOG_NONE, "Emit Interruption 0x%x at IP=%p(%s / %s) / addr=%p\n", num, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
}
- my_sigactionhandler_oldcode(SIGSEGV, 0, &info, &ctx, NULL, NULL);
+ my_sigactionhandler_oldcode(SIGSEGV, 0, &info, NULL, NULL, NULL);
+}
+
+void emit_div0(x64emu_t* emu, void* addr, int code)
+{
+ siginfo_t info = {0};
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0xcafe;
+ info.si_code = code;
+ info.si_addr = addr;
+ const char* x64name = NULL;
+ const char* elfname = NULL;
+ if(box64_log>LOG_INFO || box64_dynarec_dump || box64_showsegv) {
+ x64name = getAddrFunctionName(R_RIP);
+ elfheader_t* elf = FindElfAddress(my_context, R_RIP);
+ if(elf)
+ elfname = ElfName(elf);
+ printf_log(LOG_NONE, "Emit Divide by 0 at IP=%p(%s / %s) / addr=%p\n", (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
+ }
+ my_sigactionhandler_oldcode(SIGSEGV, 0, &info, NULL, NULL, NULL);
}
EXPORT sighandler_t my_signal(x64emu_t* emu, int signum, sighandler_t handler)
{
- if(signum<0 || signum>=MAX_SIGNAL)
+ if(signum<0 || signum>MAX_SIGNAL)
return SIG_ERR;
if(signum==SIGSEGV && emu->context->no_sigsegv)
@@ -1445,7 +1792,7 @@ EXPORT sighandler_t my_sysv_signal(x64emu_t* emu, int signum, sighandler_t handl
int EXPORT my_sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x64_sigaction_t *oldact)
{
printf_log(LOG_DEBUG, "Sigaction(signum=%d, act=%p(f=%p, flags=0x%x), old=%p)\n", signum, act, act?act->_u._sa_handler:NULL, act?act->sa_flags:0, oldact);
- if(signum<0 || signum>=MAX_SIGNAL) {
+ if(signum<0 || signum>MAX_SIGNAL) {
errno = EINVAL;
return -1;
}
@@ -1502,7 +1849,7 @@ __attribute__((alias("my_sigaction")));
int EXPORT my_syscall_rt_sigaction(x64emu_t* emu, int signum, const x64_sigaction_restorer_t *act, x64_sigaction_restorer_t *oldact, int sigsetsize)
{
printf_log(LOG_DEBUG, "Syscall/Sigaction(signum=%d, act=%p, old=%p, size=%d)\n", signum, act, oldact, sigsetsize);
- if(signum<0 || signum>=MAX_SIGNAL) {
+ if(signum<0 || signum>MAX_SIGNAL) {
errno = EINVAL;
return -1;
}
@@ -1765,7 +2112,7 @@ static void atfork_child_dynarec_prot(void)
void init_signal_helper(box64context_t* context)
{
// setup signal handling
- for(int i=0; i<MAX_SIGNAL; ++i) {
+ for(int i=0; i<=MAX_SIGNAL; ++i) {
context->signals[i] = 0; // SIG_DFL
}
struct sigaction action = {0};
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index 90c665e..e4f91d1 100644
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -24,6 +24,7 @@
#include "x64trace.h"
#include "dynarec.h"
#include "bridge.h"
+#include "myalign.h"
#ifdef DYNAREC
#include "dynablock.h"
#include "dynarec/native_lock.h"
@@ -53,17 +54,6 @@ typedef struct threadstack_s {
size_t stacksize;
} threadstack_t;
-// longjmp / setjmp
-typedef struct jump_buff_x64_s {
- uint64_t save_reg[8];
-} jump_buff_x64_t;
-
-typedef struct __jmp_buf_tag_s {
- jump_buff_x64_t __jmpbuf;
- int __mask_was_saved;
- __sigset_t __saved_mask;
-} __jmp_buf_tag_t;
-
typedef struct x64_unwind_buff_s {
struct {
jump_buff_x64_t __cancel_jmp_buf;
@@ -75,7 +65,9 @@ typedef struct x64_unwind_buff_s {
typedef void(*vFv_t)();
KHASH_MAP_INIT_INT64(threadstack, threadstack_t*)
+#ifndef ANDROID
KHASH_MAP_INIT_INT64(cancelthread, __pthread_unwind_buf_t*)
+#endif
void CleanStackSize(box64context_t* context)
{
@@ -133,50 +125,49 @@ int GetStackSize(x64emu_t* emu, uintptr_t attr, void** stack, size_t* stacksize)
return 0;
}
-static void InitCancelThread()
-{
-}
-
-static void FreeCancelThread(box64context_t* context)
-{
- if(!context)
- return;
-}
-static __pthread_unwind_buf_t* AddCancelThread(x64_unwind_buff_t* buff)
-{
- __pthread_unwind_buf_t* r = (__pthread_unwind_buf_t*)box_calloc(1, sizeof(__pthread_unwind_buf_t));
- buff->__pad[3] = r;
- return r;
-}
-
-static __pthread_unwind_buf_t* GetCancelThread(x64_unwind_buff_t* buff)
-{
- return (__pthread_unwind_buf_t*)buff->__pad[3];
-}
-
-static void DelCancelThread(x64_unwind_buff_t* buff)
-{
- __pthread_unwind_buf_t* r = (__pthread_unwind_buf_t*)buff->__pad[3];
- box_free(r);
- buff->__pad[3] = NULL;
-}
+void my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
typedef struct emuthread_s {
uintptr_t fnc;
void* arg;
x64emu_t* emu;
+ int cancel_cap, cancel_size;
+ x64_unwind_buff_t **cancels;
} emuthread_t;
+static pthread_key_t thread_key;
+
static void emuthread_destroy(void* p)
{
emuthread_t *et = (emuthread_t*)p;
+ if(!et)
+ return;
+ void* ptr;
+ // check tlsdata
+ /*if (my_context && (ptr = pthread_getspecific(my_context->tlskey)) != NULL)
+ free_tlsdatasize(ptr);*/
+ // free x64emu
if(et) {
FreeX64Emu(&et->emu);
box_free(et);
}
}
-static pthread_key_t thread_key;
+static void emuthread_cancel(void* p)
+{
+ emuthread_t *et = (emuthread_t*)p;
+ if(!et)
+ return;
+ // check cancels threads
+ for(int i=et->cancel_size-1; i>=0; --i) {
+ et->emu->flags.quitonlongjmp = 0;
+ my_longjmp(et->emu, et->cancels[i]->__cancel_jmp_buf, 1);
+ DynaRun(et->emu); // will return after a __pthread_unwind_next()
+ }
+ box_free(et->cancels);
+ et->cancels=NULL;
+ et->cancel_size = et->cancel_cap = 0;
+}
void thread_set_emu(x64emu_t* emu)
{
@@ -248,7 +239,9 @@ static void* pthread_routine(void* p)
PushExit(emu);
R_RIP = et->fnc;
R_RDI = (uintptr_t)et->arg;
+ pthread_cleanup_push(emuthread_cancel, p);
DynaRun(emu);
+ pthread_cleanup_pop(0);
void* ret = (void*)R_RAX;
//void* ret = (void*)RunFunctionWithEmu(et->emu, 0, et->fnc, 1, et->arg);
return ret;
@@ -346,11 +339,13 @@ EXPORT int my_pthread_attr_getguardsize(x64emu_t* emu, pthread_attr_t* attr, siz
(void)emu;
return pthread_attr_getguardsize(getAlignedAttr(attr), size);
}
+#ifndef TERMUX
EXPORT int my_pthread_attr_getinheritsched(x64emu_t* emu, pthread_attr_t* attr, int* sched)
{
(void)emu;
return pthread_attr_getinheritsched(getAlignedAttr(attr), sched);
}
+#endif
EXPORT int my_pthread_attr_getschedparam(x64emu_t* emu, pthread_attr_t* attr, void* param)
{
(void)emu;
@@ -388,11 +383,13 @@ EXPORT int my_pthread_attr_init(x64emu_t* emu, pthread_attr_t* attr)
(void)emu;
return pthread_attr_init(getAlignedAttrWithInit(attr, 0));
}
+#ifndef ANDROID
EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset)
{
(void)emu;
return pthread_attr_setaffinity_np(getAlignedAttr(attr), cpusize, cpuset);
}
+#endif
EXPORT int my_pthread_attr_setdetachstate(x64emu_t* emu, pthread_attr_t* attr, int state)
{
(void)emu;
@@ -403,11 +400,13 @@ EXPORT int my_pthread_attr_setguardsize(x64emu_t* emu, pthread_attr_t* attr, siz
(void)emu;
return pthread_attr_setguardsize(getAlignedAttr(attr), size);
}
+#ifndef TERMUX
EXPORT int my_pthread_attr_setinheritsched(x64emu_t* emu, pthread_attr_t* attr, int sched)
{
(void)emu;
return pthread_attr_setinheritsched(getAlignedAttr(attr), sched);
}
+#endif
EXPORT int my_pthread_attr_setschedparam(x64emu_t* emu, pthread_attr_t* attr, void* param)
{
(void)emu;
@@ -430,6 +429,7 @@ EXPORT int my_pthread_attr_setstackaddr(x64emu_t* emu, pthread_attr_t* attr, voi
return pthread_attr_setstack(getAlignedAttr(attr), addr, size);
//return pthread_attr_setstackaddr(getAlignedAttr(attr), addr);
}
+#ifndef ANDROID
EXPORT int my_pthread_getattr_np(x64emu_t* emu, pthread_t thread_id, pthread_attr_t* attr)
{
(void)emu;
@@ -462,6 +462,7 @@ EXPORT int my_pthread_setattr_default_np(x64emu_t* emu, pthread_attr_t* attr)
(void)emu;
return pthread_setattr_default_np(getAlignedAttr(attr));
}
+#endif //!ANDROID
#endif
EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_routine, void* arg)
@@ -524,58 +525,30 @@ void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet
return pthread_routine;
}
-void my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
-
-#define CANCEL_MAX 8
-static __thread x64emu_t* cancel_emu[CANCEL_MAX] = {0};
-static __thread x64_unwind_buff_t* cancel_buff[CANCEL_MAX] = {0};
-static __thread int cancel_deep = 0;
-EXPORT void my___pthread_register_cancel(void* E, void* B)
+EXPORT void my___pthread_register_cancel(x64emu_t* emu, x64_unwind_buff_t* buff)
{
- // get a stack local copy of the args, as may be live in some register depending the architecture (like ARM)
- if(cancel_deep<0) {
- printf_log(LOG_NONE/*LOG_INFO*/, "BOX64: Warning, inconsistent value in __pthread_register_cancel (%d)\n", cancel_deep);
- cancel_deep = 0;
- }
- if(cancel_deep!=CANCEL_MAX-1)
- ++cancel_deep;
- else
- {printf_log(LOG_NONE/*LOG_INFO*/, "BOX64: Warning, calling __pthread_register_cancel(...) too many time\n");}
-
- cancel_emu[cancel_deep] = (x64emu_t*)E;
-
- x64_unwind_buff_t* buff = cancel_buff[cancel_deep] = (x64_unwind_buff_t*)B;
- __pthread_unwind_buf_t * pbuff = AddCancelThread(buff);
- if(__sigsetjmp((struct __jmp_buf_tag*)(void*)pbuff->__cancel_jmp_buf, 0)) {
- //DelCancelThread(cancel_buff); // no del here, it will be delete by unwind_next...
- int i = cancel_deep--;
- x64emu_t* emu = cancel_emu[i];
- my_longjmp(emu, cancel_buff[i]->__cancel_jmp_buf, 1);
- DynaRun(emu); // resume execution // TODO: Use ejb instead?
- return;
+ emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
+ if(et->cancel_cap == et->cancel_size) {
+ et->cancel_cap+=8;
+ et->cancels = box_realloc(et->cancels, sizeof(x64_unwind_buff_t*)*et->cancel_cap);
}
-
- __pthread_register_cancel(pbuff);
+ et->cancels[et->cancel_size++] = buff;
}
EXPORT void my___pthread_unregister_cancel(x64emu_t* emu, x64_unwind_buff_t* buff)
{
- (void)emu;
- __pthread_unwind_buf_t * pbuff = GetCancelThread(buff);
- __pthread_unregister_cancel(pbuff);
-
- --cancel_deep;
- DelCancelThread(buff);
+ emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
+ for (int i=et->cancel_size-1; i>=0; --i) {
+ if(et->cancels[i] == buff) {
+ if(i!=et->cancel_size-1)
+ memmove(et->cancels+i, et->cancels+i+1, sizeof(x64_unwind_buff_t*)*(et->cancel_size-i-1));
+ et->cancel_size--;
+ }
+ }
}
EXPORT void my___pthread_unwind_next(x64emu_t* emu, x64_unwind_buff_t* buff)
{
- (void)emu;
- __pthread_unwind_buf_t pbuff = *GetCancelThread(buff);
- DelCancelThread(buff);
- // function is noreturn, putting stuff on the stack to have it auto-free (is that correct?)
- __pthread_unwind_next(&pbuff);
- // just in case it does return
emu->quit = 1;
}
@@ -613,48 +586,49 @@ GO(27) \
GO(28) \
GO(29)
-// key_destructor
+// cleanup_routine
#define GO(A) \
-static uintptr_t my_key_destructor_fct_##A = 0; \
-static void my_key_destructor_##A(void* a) \
+static uintptr_t my_cleanup_routine_fct_##A = 0; \
+static void my_cleanup_routine_##A(void* a) \
{ \
- RunFunction(my_key_destructor_fct_##A, 1, a);\
+ RunFunction(my_cleanup_routine_fct_##A, 1, a);\
}
SUPER()
#undef GO
-static void* findkey_destructorFct(void* fct)
+static void* findcleanup_routineFct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
- #define GO(A) if(my_key_destructor_fct_##A == (uintptr_t)fct) return my_key_destructor_##A;
+ #define GO(A) if(my_cleanup_routine_fct_##A == (uintptr_t)fct) return my_cleanup_routine_##A;
SUPER()
#undef GO
- #define GO(A) if(my_key_destructor_fct_##A == 0) {my_key_destructor_fct_##A = (uintptr_t)fct; return my_key_destructor_##A; }
+ #define GO(A) if(my_cleanup_routine_fct_##A == 0) {my_cleanup_routine_fct_##A = (uintptr_t)fct; return my_cleanup_routine_##A; }
SUPER()
#undef GO
- printf_log(LOG_NONE, "Warning, no more slot for pthread key_destructor callback\n");
+ printf_log(LOG_NONE, "Warning, no more slot for pthread cleanup_routine callback\n");
return NULL;
}
-// cleanup_routine
+
+// key_dtor
#define GO(A) \
-static uintptr_t my_cleanup_routine_fct_##A = 0; \
-static void my_cleanup_routine_##A(void* a) \
+static uintptr_t my_key_dtor_fct_##A = 0; \
+static void my_key_dtor_##A(void* a) \
{ \
- RunFunction(my_cleanup_routine_fct_##A, 1, a);\
+ RunFunction(my_key_dtor_fct_##A, 1, a);\
}
SUPER()
#undef GO
-static void* findcleanup_routineFct(void* fct)
+static void* findkey_dtorFct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
- #define GO(A) if(my_cleanup_routine_fct_##A == (uintptr_t)fct) return my_cleanup_routine_##A;
+ #define GO(A) if(my_key_dtor_fct_##A == (uintptr_t)fct) return my_key_dtor_##A;
SUPER()
#undef GO
- #define GO(A) if(my_cleanup_routine_fct_##A == 0) {my_cleanup_routine_fct_##A = (uintptr_t)fct; return my_cleanup_routine_##A; }
+ #define GO(A) if(my_key_dtor_fct_##A == 0) {my_key_dtor_fct_##A = (uintptr_t)fct; return my_key_dtor_##A; }
SUPER()
#undef GO
- printf_log(LOG_NONE, "Warning, no more slot for pthread cleanup_routine callback\n");
+ printf_log(LOG_NONE, "Warning, no more slot for pthread key_dtor callback\n");
return NULL;
}
@@ -683,14 +657,21 @@ int EXPORT my_pthread_once(x64emu_t* emu, int* once, void* cb)
}
EXPORT int my___pthread_once(x64emu_t* emu, void* once, void* cb) __attribute__((alias("my_pthread_once")));
-EXPORT int my_pthread_key_create(x64emu_t* emu, void* key, void* dtor)
+EXPORT int my_pthread_key_create(x64emu_t* emu, pthread_key_t* key, void* dtor)
{
(void)emu;
- return pthread_key_create(key, findkey_destructorFct(dtor));
+ int ret = pthread_key_create(key, findkey_dtorFct(dtor));
+ return ret;
+}
+EXPORT int my___pthread_key_create(x64emu_t* emu, pthread_key_t* key, void* dtor) __attribute__((alias("my_pthread_key_create")));
+
+EXPORT int my_pthread_key_delete(x64emu_t* emu, pthread_key_t key)
+{
+ int ret = pthread_key_delete(key);
+ return ret;
}
-EXPORT int my___pthread_key_create(x64emu_t* emu, void* key, void* dtor) __attribute__((alias("my_pthread_key_create")));
-pthread_cond_t* alignCond(pthread_cond_t* pc)
+static pthread_cond_t* alignCond(pthread_cond_t* pc)
{
#ifndef NOALIGN
if((uintptr_t)pc&7)
@@ -724,6 +705,7 @@ EXPORT int my_pthread_cond_clockwait(x64emu_t *emu, pthread_cond_t* cond, void*
return ret;
}
+#ifndef ANDROID
EXPORT void my__pthread_cleanup_push_defer(x64emu_t* emu, void* buffer, void* routine, void* arg)
{
(void)emu;
@@ -769,6 +751,7 @@ EXPORT int my_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, size_t cpu
return ret;
}
+#endif
//EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, void* attr, uint32_t cpusetsize, void* cpuset)
//{
@@ -829,6 +812,7 @@ EXPORT int my_pthread_mutexattr_getkind_np(x64emu_t* emu, my_mutexattr_t *attr,
attr->x86 = mattr.x86;
return ret;
}
+#ifndef TERMUX
EXPORT int my_pthread_mutexattr_getprotocol(x64emu_t* emu, my_mutexattr_t *attr, void* p)
{
my_mutexattr_t mattr = {0};
@@ -837,6 +821,7 @@ EXPORT int my_pthread_mutexattr_getprotocol(x64emu_t* emu, my_mutexattr_t *attr,
attr->x86 = mattr.x86;
return ret;
}
+#endif
EXPORT int my_pthread_mutexattr_gettype(x64emu_t* emu, my_mutexattr_t *attr, void* p)
{
my_mutexattr_t mattr = {0};
@@ -845,6 +830,7 @@ EXPORT int my_pthread_mutexattr_gettype(x64emu_t* emu, my_mutexattr_t *attr, voi
attr->x86 = mattr.x86;
return ret;
}
+#ifndef ANDROID
EXPORT int my_pthread_mutexattr_getrobust(x64emu_t* emu, my_mutexattr_t *attr, void* p)
{
my_mutexattr_t mattr = {0};
@@ -853,6 +839,7 @@ EXPORT int my_pthread_mutexattr_getrobust(x64emu_t* emu, my_mutexattr_t *attr, v
attr->x86 = mattr.x86;
return ret;
}
+#endif
EXPORT int my_pthread_mutexattr_init(x64emu_t* emu, my_mutexattr_t *attr)
{
my_mutexattr_t mattr = {0};
@@ -871,6 +858,7 @@ EXPORT int my_pthread_mutexattr_setkind_np(x64emu_t* emu, my_mutexattr_t *attr,
attr->x86 = mattr.x86;
return ret;
}
+#ifndef TERMUX
EXPORT int my_pthread_mutexattr_setprotocol(x64emu_t* emu, my_mutexattr_t *attr, int p)
{
my_mutexattr_t mattr = {0};
@@ -879,6 +867,7 @@ EXPORT int my_pthread_mutexattr_setprotocol(x64emu_t* emu, my_mutexattr_t *attr,
attr->x86 = mattr.x86;
return ret;
}
+#endif
EXPORT int my_pthread_mutexattr_setpshared(x64emu_t* emu, my_mutexattr_t *attr, int p)
{
my_mutexattr_t mattr = {0};
@@ -896,6 +885,7 @@ EXPORT int my_pthread_mutexattr_settype(x64emu_t* emu, my_mutexattr_t *attr, int
return ret;
}
EXPORT int my___pthread_mutexattr_settype(x64emu_t* emu, my_mutexattr_t *attr, int t) __attribute__((alias("my_pthread_mutexattr_settype")));
+#ifndef ANDROID
EXPORT int my_pthread_mutexattr_setrobust(x64emu_t* emu, my_mutexattr_t *attr, int t)
{
my_mutexattr_t mattr = {0};
@@ -904,6 +894,7 @@ EXPORT int my_pthread_mutexattr_setrobust(x64emu_t* emu, my_mutexattr_t *attr, i
attr->x86 = mattr.x86;
return ret;
}
+#endif
#ifdef __SIZEOF_PTHREAD_MUTEX_T
#if __SIZEOF_PTHREAD_MUTEX_T == 48
@@ -1085,15 +1076,12 @@ void init_pthread_helper()
real_phtread_kill_old = (iFli_t)pthread_kill;
}
- InitCancelThread();
pthread_key_create(&thread_key, emuthread_destroy);
pthread_setspecific(thread_key, NULL);
}
-void fini_pthread_helper(box64context_t* context)
+void clean_current_emuthread()
{
- FreeCancelThread(context);
- CleanStackSize(context);
emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
if(et) {
pthread_setspecific(thread_key, NULL);
@@ -1101,6 +1089,12 @@ void fini_pthread_helper(box64context_t* context)
}
}
+void fini_pthread_helper(box64context_t* context)
+{
+ CleanStackSize(context);
+ clean_current_emuthread();
+}
+
int checkUnlockMutex(void* m)
{
pthread_mutex_t* mutex = (pthread_mutex_t*)m;
diff --git a/src/main.c b/src/main.c
index 14e04d1..db33d9a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -46,7 +46,9 @@ int box64_dynarec_log = LOG_NONE;
uintptr_t box64_pagesize;
uintptr_t box64_load_addr = 0;
int box64_nosandbox = 0;
+int box64_inprocessgpu = 0;
int box64_malloc_hack = 0;
+int box64_dynarec_test = 0;
#ifdef DYNAREC
int box64_dynarec = 1;
int box64_dynarec_dump = 0;
@@ -58,14 +60,15 @@ int box64_dynarec_x87double = 0;
int box64_dynarec_fastnan = 1;
int box64_dynarec_fastround = 1;
int box64_dynarec_safeflags = 1;
-int box64_dynarec_callret = 0;
+int box64_dynarec_callret = 1;
int box64_dynarec_hotpage = 0;
int box64_dynarec_fastpage = 0;
int box64_dynarec_bleeding_edge = 1;
int box64_dynarec_jvm = 1;
+int box64_dynarec_tbb = 1;
int box64_dynarec_wait = 1;
-int box64_dynarec_test = 0;
int box64_dynarec_missing = 0;
+int box64_dynarec_aligned_atomics = 0;
uintptr_t box64_nodynarec_start = 0;
uintptr_t box64_nodynarec_end = 0;
#ifdef ARM64
@@ -74,16 +77,33 @@ int arm64_aes = 0;
int arm64_pmull = 0;
int arm64_crc32 = 0;
int arm64_atomics = 0;
+int arm64_sha1 = 0;
+int arm64_sha2 = 0;
+int arm64_uscat = 0;
+int arm64_flagm = 0;
+int arm64_flagm2 = 0;
+int arm64_frintts = 0;
+int arm64_afp = 0;
#elif defined(RV64)
int rv64_zba = 0;
int rv64_zbb = 0;
int rv64_zbc = 0;
int rv64_zbs = 0;
+int rv64_xtheadba = 0;
+int rv64_xtheadbb = 0;
+int rv64_xtheadbs = 0;
+int rv64_xtheadcondmov = 0;
+int rv64_xtheadmemidx = 0;
+int rv64_xtheadmempair = 0;
+int rv64_xtheadfmemidx = 0;
+int rv64_xtheadmac = 0;
+int rv64_xtheadfmv = 0;
#endif
#else //DYNAREC
int box64_dynarec = 0;
#endif
int box64_libcef = 1;
+int box64_sdl2_jguid = 0;
int dlsym_error = 0;
int cycle_log = 0;
#ifdef HAVE_TRACE
@@ -106,6 +126,7 @@ int box64_prefer_emulated = 0;
int box64_prefer_wrapped = 0;
int box64_sse_flushto0 = 0;
int box64_x87_no80bits = 0;
+int box64_sync_rounding = 0;
int fix_64bit_inodes = 0;
int box64_dummy_crashhandler = 1;
int box64_mapclean = 0;
@@ -119,7 +140,13 @@ int box64_novulkan = 0;
int box64_showsegv = 0;
int box64_showbt = 0;
int box64_isglibc234 = 0;
+#ifdef BAD_SIGNAL
+int box64_futex_waitv = 0;
+#else
+int box64_futex_waitv = 1;
+#endif
char* box64_libGL = NULL;
+char* box64_custom_gstreamer = NULL;
uintptr_t fmod_smc_start = 0;
uintptr_t fmod_smc_end = 0;
uint32_t default_gs = 0x53;
@@ -133,19 +160,22 @@ int ftrace_has_pid = 0;
void openFTrace(const char* newtrace)
{
const char* t = newtrace?newtrace:getenv("BOX64_TRACE_FILE");
- char tmp[500];
- char tmp2[500];
+ #ifndef MAX_PATH
+ #define MAX_PATH 4096
+ #endif
+ char tmp[MAX_PATH];
+ char tmp2[MAX_PATH];
const char* p = t;
int append=0;
if(p && strlen(p) && p[strlen(p)-1]=='+') {
- strncat(tmp2, t, 499);
+ strncpy(tmp2, p, sizeof(tmp2));
tmp2[strlen(p)-1]='\0';
p = tmp2;
append=1;
}
- if(p && strstr(t, "%pid")) {
+ if(p && strstr(p, "%pid")) {
int next = 0;
- if(!append) do {
+ do {
strcpy(tmp, p);
char* c = strstr(tmp, "%pid");
*c = 0; // cut
@@ -158,7 +188,7 @@ void openFTrace(const char* newtrace)
c = strstr(p, "%pid") + strlen("%pid");
strcat(tmp, c);
++next;
- } while (FileExist(tmp, IS_FILE));
+ } while (FileExist(tmp, IS_FILE) && !append);
p = tmp;
ftrace_has_pid = 1;
}
@@ -208,7 +238,7 @@ void my_child_fork()
{
if(ftrace_has_pid) {
// open a new ftrace...
- if(!ftrace_name)
+ if(!ftrace_name)
fclose(ftrace);
openFTrace(NULL);
}
@@ -231,17 +261,17 @@ HWCAP_EVTSTRM
The generic timer is configured to generate events at a frequency of
approximately 10KHz.
HWCAP_AES
- Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0001. => AESE, AESD, AESMC, and AESIMC instructions are implemented
HWCAP_PMULL
- Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0010.
+ Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0010. => AESE, AESD, AESMC, and AESIMC instructions are implemented plus PMULL/PMULL2 instructions operating on 64-bit data quantities.
HWCAP_SHA1
- Functionality implied by ID_AA64ISAR0_EL1.SHA1 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.SHA1 == 0b0001. => SHA1C, SHA1P, SHA1M, SHA1H, SHA1SU0, and SHA1SU1 instructions implemented.
HWCAP_SHA2
- Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0001. => SHA256H, SHA256H2, SHA256SU0 and SHA256SU1 instructions implemented.
HWCAP_CRC32
- Functionality implied by ID_AA64ISAR0_EL1.CRC32 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.CRC32 == 0b0001. => CRC32B, CRC32H, CRC32W, CRC32X, CRC32CB, CRC32CH, CRC32CW, and CRC32CX instructions implemented.
HWCAP_ATOMICS
- Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0010.
+ Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0010. => LDADD, LDCLR, LDEOR, LDSET, LDSMAX, LDSMIN, LDUMAX, LDUMIN, CAS, CASP, and SWP instructions implemented.
HWCAP_FPHP
Functionality implied by ID_AA64PFR0_EL1.FP == 0b0001.
HWCAP_ASIMDHP
@@ -250,49 +280,49 @@ HWCAP_CPUID
EL0 access to certain ID registers is available.
These ID registers may imply the availability of features.
HWCAP_ASIMDRDM
- Functionality implied by ID_AA64ISAR0_EL1.RDM == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.RDM == 0b0001. => SQRDMLAH and SQRDMLSH instructions implemented.
HWCAP_JSCVT
- Functionality implied by ID_AA64ISAR1_EL1.JSCVT == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.JSCVT == 0b0001. => The FJCVTZS instruction is implemented.
HWCAP_FCMA
- Functionality implied by ID_AA64ISAR1_EL1.FCMA == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.FCMA == 0b0001. => The FCMLA and FCADD instructions are implemented.
HWCAP_LRCPC
- Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0001. => LDAPR and variants
HWCAP_DCPOP
Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0001.
HWCAP_SHA3
- Functionality implied by ID_AA64ISAR0_EL1.SHA3 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.SHA3 == 0b0001. => EOR3, RAX1, XAR, and BCAX instructions implemented.
HWCAP_SM3
- Functionality implied by ID_AA64ISAR0_EL1.SM3 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.SM3 == 0b0001. => SM3SS1, SM3TT1A, SM3TT1B, SM3TT2A, SM3TT2B, SM3PARTW1, and SM3PARTW2 instructions implemented.
HWCAP_SM4
- Functionality implied by ID_AA64ISAR0_EL1.SM4 == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.SM4 == 0b0001. => SM4E and SM4EKEY instructions implemented.
HWCAP_ASIMDDP
- Functionality implied by ID_AA64ISAR0_EL1.DP == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.DP == 0b0001. => UDOT and SDOT instructions implemented.
HWCAP_SHA512
- Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0010.
+ Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0010. => SHA512H, SHA512H2, SHA512SU0, and SHA512SU1 instructions implemented.
HWCAP_SVE
Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001.
HWCAP_ASIMDFHM
- Functionality implied by ID_AA64ISAR0_EL1.FHM == 0b0001.
+ Functionality implied by ID_AA64ISAR0_EL1.FHM == 0b0001. => FMLAL and FMLSL instructions are implemented.
HWCAP_DIT
Functionality implied by ID_AA64PFR0_EL1.DIT == 0b0001.
HWCAP_USCAT
Functionality implied by ID_AA64MMFR2_EL1.AT == 0b0001.
HWCAP_ILRCPC
- Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0010.
+ Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0010. => The LDAPUR*, STLUR*, and LDAPR* instructions are implemented.
HWCAP_FLAGM
Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0001.
HWCAP_SSBS
- Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010.
+ Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010. => AArch64 provides the PSTATE.SSBS mechanism to mark regions that are Speculative Store Bypassing Safe, and the MSR and MRS instructions to directly read and write the PSTATE.SSBS field.
HWCAP_SB
- Functionality implied by ID_AA64ISAR1_EL1.SB == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.SB == 0b0001. => SB instruction is implemented.
HWCAP_PACA
Functionality implied by ID_AA64ISAR1_EL1.APA == 0b0001 or
ID_AA64ISAR1_EL1.API == 0b0001.
HWCAP_PACG
- Functionality implied by ID_AA64ISAR1_EL1.GPA == 0b0001 or
+ Functionality implied by ID_AA64ISAR1_EL1.GPA == 0b0001 or => Generic Authentication using the QARMA algorithm is implemented. This includes the PACGA instruction.
ID_AA64ISAR1_EL1.GPI == 0b0001.
HWCAP2_DCPODP
- Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
+ Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010. => DC CVAP and DC CVADP supported
HWCAP2_SVE2
Functionality implied by ID_AA64ZFR0_EL1.SVEVer == 0b0001.
HWCAP2_SVEAES
@@ -306,9 +336,9 @@ HWCAP2_SVESHA3
HWCAP2_SVESM4
Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001.
HWCAP2_FLAGM2
- Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010.
+ Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010. => CFINV, RMIF, SETF16, SETF8, AXFLAG, and XAFLAG instructions are implemented.
HWCAP2_FRINT
- Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001. => FRINT32Z, FRINT32X, FRINT64Z, and FRINT64X instructions are implemented.
HWCAP2_SVEI8MM
Functionality implied by ID_AA64ZFR0_EL1.I8MM == 0b0001.
HWCAP2_SVEF32MM
@@ -316,19 +346,19 @@ HWCAP2_SVEF32MM
HWCAP2_SVEF64MM
Functionality implied by ID_AA64ZFR0_EL1.F64MM == 0b0001.
HWCAP2_SVEBF16
- Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001.
+ Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001
HWCAP2_I8MM
- Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001. => SMMLA, SUDOT, UMMLA, USMMLA, and USDOT instructions are implemented
HWCAP2_BF16
- Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0001. => BFDOT, BFMLAL, BFMLAL2, BFMMLA, BFCVT, and BFCVT2 instructions are implemented.
HWCAP2_DGH
- Functionality implied by ID_AA64ISAR1_EL1.DGH == 0b0001.
+ Functionality implied by ID_AA64ISAR1_EL1.DGH == 0b0001. => Data Gathering Hint is implemented.
HWCAP2_RNG
Functionality implied by ID_AA64ISAR0_EL1.RNDR == 0b0001.
HWCAP2_BTI
Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001.
HWCAP2_MTE
- Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010.
+ Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010. => Full Memory Tagging Extension is implemented.
HWCAP2_ECV
Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001.
*/
@@ -347,8 +377,38 @@ HWCAP2_ECV
arm64_pmull = 1;
if(hwcap&HWCAP_AES)
arm64_aes = 1;
- if(hwcap&HWCAP_ATOMICS)
- arm64_atomics = 1;
+ // ATOMIC use are disable for now. They crashes Batman Arkham Knight, bossibly other (also seems to make steamwebhelper unstable)
+ /*if(hwcap&HWCAP_ATOMICS)
+ arm64_atomics = 1;*/
+ #ifdef HWCAP_SHA1
+ if(hwcap&HWCAP_SHA1)
+ arm64_sha1 = 1;
+ #endif
+ #ifdef HWCAP_SHA2
+ if(hwcap&HWCAP_SHA2)
+ arm64_sha2 = 1;
+ #endif
+ #ifdef HWCAP_USCAT
+ if(hwcap&HWCAP_USCAT)
+ arm64_uscat = 1;
+ #endif
+ #ifdef HWCAP_FLAGM
+ if(hwcap&HWCAP_FLAGM)
+ arm64_flagm = 1;
+ #endif
+ unsigned long hwcap2 = real_getauxval(AT_HWCAP2);
+ #ifdef HWCAP2_FLAGM2
+ if(hwcap2&HWCAP2_FLAGM2)
+ arm64_flagm2 = 1;
+ #endif
+ #ifdef HWCAP2_FRINT
+ if(hwcap2&HWCAP2_FRINT)
+ arm64_frintts = 1;
+ #endif
+ #ifdef HWCAP2_AFP
+ if(hwcap2&HWCAP2_AFP)
+ arm64_afp = 1;
+ #endif
printf_log(LOG_INFO, "Dynarec for ARM64, with extension: ASIMD");
if(arm64_aes)
printf_log(LOG_INFO, " AES");
@@ -358,6 +418,20 @@ HWCAP2_ECV
printf_log(LOG_INFO, " PMULL");
if(arm64_atomics)
printf_log(LOG_INFO, " ATOMICS");
+ if(arm64_sha1)
+ printf_log(LOG_INFO, " SHA1");
+ if(arm64_sha2)
+ printf_log(LOG_INFO, " SHA2");
+ if(arm64_uscat)
+ printf_log(LOG_INFO, " USCAT");
+ if(arm64_flagm)
+ printf_log(LOG_INFO, " FLAGM");
+ if(arm64_flagm2)
+ printf_log(LOG_INFO, " FLAGM2");
+ if(arm64_frintts)
+ printf_log(LOG_INFO, " FRINT");
+ if(arm64_afp)
+ printf_log(LOG_INFO, " AFP");
printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
#elif defined(LA464)
printf_log(LOG_INFO, "Dynarec for LoongArch");
@@ -372,6 +446,16 @@ HWCAP2_ECV
if(rv64_zbb) printf_log(LOG_INFO, " Zbb");
if(rv64_zbc) printf_log(LOG_INFO, " Zbc");
if(rv64_zbs) printf_log(LOG_INFO, " Zbs");
+ if(rv64_xtheadba) printf_log(LOG_INFO, " XTheadBa");
+ if(rv64_xtheadbb) printf_log(LOG_INFO, " XTheadBb");
+ if(rv64_xtheadbs) printf_log(LOG_INFO, " XTheadBs");
+ if(rv64_xtheadcondmov) printf_log(LOG_INFO, " XTheadCondMov");
+ if(rv64_xtheadmemidx) printf_log(LOG_INFO, " XTheadMemIdx");
+ if(rv64_xtheadmempair) printf_log(LOG_INFO, " XTheadMemPair");
+ if(rv64_xtheadfmemidx) printf_log(LOG_INFO, " XTheadFMemIdx");
+ if(rv64_xtheadmac) printf_log(LOG_INFO, " XTheadMac");
+ if(rv64_xtheadfmv) printf_log(LOG_INFO, " XTheadFmv");
+
printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
#else
#error Unsupported architecture
@@ -446,6 +530,11 @@ void LoadLogEnv()
if(!box64_nobanner && box64_dump)
printf_log(LOG_INFO, "Elf Dump if ON\n");
#ifdef DYNAREC
+ #ifdef ARM64
+ // unaligned atomic (with restriction) is supported in hardware
+ /*if(arm64_uscat)
+ box64_dynarec_aligned_atomics = 1;*/ // the unaligned support is not good enough for x86 emulation, so diabling
+ #endif
p = getenv("BOX64_DYNAREC_DUMP");
if(p) {
if(strlen(p)==1) {
@@ -515,11 +604,11 @@ void LoadLogEnv()
p = getenv("BOX64_DYNAREC_STRONGMEM");
if(p) {
if(strlen(p)==1) {
- if(p[0]>='0' && p[0]<='2')
+ if(p[0]>='0' && p[0]<='3')
box64_dynarec_strongmem = p[0]-'0';
}
if(box64_dynarec_strongmem)
- printf_log(LOG_INFO, "Dynarec will try to emulate a strong memory model%s\n", (box64_dynarec_strongmem==1)?" with limited performance loss":"");
+ printf_log(LOG_INFO, "Dynarec will try to emulate a strong memory model%s\n", (box64_dynarec_strongmem==1)?" with limited performance loss":((box64_dynarec_strongmem==3)?" with more performance loss":""));
}
p = getenv("BOX64_DYNAREC_X87DOUBLE");
if(p) {
@@ -567,6 +656,8 @@ void LoadLogEnv()
}
if(box64_dynarec_callret)
printf_log(LOG_INFO, "Dynarec will optimize CALL/RET\n");
+ else
+ printf_log(LOG_INFO, "Dynarec will not optimize CALL/RET\n");
}
p = getenv("BOX64_DYNAREC_BLEEDING_EDGE");
if(p) {
@@ -586,6 +677,15 @@ void LoadLogEnv()
if(!box64_dynarec_jvm)
printf_log(LOG_INFO, "Dynarec will not detect libjvm\n");
}
+ p = getenv("BOX64_DYNAREC_TBB");
+ if(p) {
+ if(strlen(p)==1) {
+ if(p[0]>='0' && p[0]<='1')
+ box64_dynarec_tbb = p[0]-'0';
+ }
+ if(!box64_dynarec_tbb)
+ printf_log(LOG_INFO, "Dynarec will not detect libtbb\n");
+ }
p = getenv("BOX64_DYNAREC_WAIT");
if(p) {
if(strlen(p)==1) {
@@ -616,6 +716,15 @@ void LoadLogEnv()
if(box64_dynarec_fastpage)
printf_log(LOG_INFO, "Dynarec will use Fast HotPage\n");
}
+ p = getenv("BOX64_DYNAREC_ALIGNED_ATOMICS");
+ if(p) {
+ if(strlen(p)==1) {
+ if(p[0]>='0' && p[0]<='1')
+ box64_dynarec_aligned_atomics = p[0]-'0';
+ }
+ if(box64_dynarec_aligned_atomics)
+ printf_log(LOG_INFO, "Dynarec will generate only aligned atomics code\n");
+ }
p = getenv("BOX64_DYNAREC_MISSING");
if(p) {
if(strlen(p)==1) {
@@ -698,7 +807,16 @@ void LoadLogEnv()
box64_libcef = p[0]-'0';
}
if(!box64_libcef)
- printf_log(LOG_INFO, "Dynarec will not detect libcef\n");
+ printf_log(LOG_INFO, "BOX64 will not detect libcef\n");
+ }
+ p = getenv("BOX64_SDL2_JGUID");
+ if(p) {
+ if(strlen(p)==1) {
+ if(p[0]>='0' && p[0]<='1')
+ box64_sdl2_jguid = p[0]-'0';
+ }
+ if(!box64_sdl2_jguid)
+ printf_log(LOG_INFO, "BOX64 will workaround the use of SDL_GetJoystickGUIDInfo with 4 args instead of 5\n");
}
p = getenv("BOX64_LOAD_ADDR");
if(p) {
@@ -803,6 +921,20 @@ void LoadLogEnv()
if(box64_novulkan)
printf_log(LOG_INFO, "Disable the use of wrapped vulkan libs\n");
}
+ p = getenv("BOX64_FUTEX_WAITV");
+ if(p) {
+ if(strlen(p)==1) {
+ if(p[0]>='0' && p[0]<='0'+1)
+ box64_futex_waitv = p[0]-'0';
+ }
+ #ifdef BAD_SIGNAL
+ if(box64_futex_waitv)
+ printf_log(LOG_INFO, "Enable the use of futex waitv syscall (if available on the system\n");
+ #else
+ if(!box64_futex_waitv)
+ printf_log(LOG_INFO, "Disable the use of futex waitv syscall\n");
+ #endif
+ }
p = getenv("BOX64_FIX_64BIT_INODES");
if(p) {
if(strlen(p)==1) {
@@ -815,11 +947,11 @@ void LoadLogEnv()
p = getenv("BOX64_JITGDB");
if(p) {
if(strlen(p)==1) {
- if(p[0]>='0' && p[0]<='0'+2)
+ if(p[0]>='0' && p[0]<='0'+3)
jit_gdb = p[0]-'0';
}
if(jit_gdb)
- printf_log(LOG_INFO, "Launch %s on segfault\n", (jit_gdb==2)?"gdbserver":"gdb");
+ printf_log(LOG_INFO, "Launch %s on segfault\n", (jit_gdb==2)?"gdbserver":((jit_gdb==3)?"lldb":"gdb"));
}
p = getenv("BOX64_SHOWSEGV");
if(p) {
@@ -855,13 +987,16 @@ void LoadEnvPath(path_collection_t *col, const char* defpath, const char* env)
{
const char* p = getenv(env);
if(p) {
- printf_log(LOG_INFO, "%s: ", env);
ParseList(p, col, 1);
} else {
- printf_log(LOG_INFO, "Using default %s: ", env);
ParseList(defpath, col, 1);
}
+}
+
+void PrintCollection(path_collection_t* col, const char* env)
+{
if(LOG_INFO<=box64_log) {
+ printf_log(LOG_INFO, "%s: ", env);
for(int i=0; i<col->size; i++)
printf_log(LOG_INFO, "%s%s", col->paths[i], (i==col->size-1)?"\n":":");
}
@@ -888,7 +1023,7 @@ int GatherEnv(char*** dest, char** env, char* prog)
{
// Add all but BOX64_* environnement
// but add 2 for default BOX64_PATH and BOX64_LD_LIBRARY_PATH
- char** p = env;
+ char** p = env;
int idx = 0;
int path = 0;
int ld_path = 0;
@@ -932,15 +1067,8 @@ int GatherEnv(char*** dest, char** env, char* prog)
return 0;
}
-
-void PrintHelp() {
- printf("\n\nThis is Box64, the Linux x86_64 emulator with a twist\n");
- printf("\nUsage is box64 [options] path/to/software [args]\n");
- printf("to launch x86_64 software\n");
- printf(" options can be :\n");
- printf(" '-v'|'--version' to print box64 version and quit\n");
- printf(" '-h'|'--help' to print box64 help and quit\n");
- printf("You can also set some environment variables:\n");
+void PrintFlags() {
+ printf("Environment Variables:\n");
printf(" BOX64_PATH is the box64 version of PATH (default is '.:bin')\n");
printf(" BOX64_LD_LIBRARY_PATH is the box64 version LD_LIBRARY_PATH (default is '.:lib:lib64')\n");
printf(" BOX64_LOG with 0/1/2/3 or NONE/INFO/DEBUG/DUMP to set the printed debug info (level 3 is level 2 + BOX64_DUMP)\n");
@@ -955,7 +1083,7 @@ void PrintHelp() {
printf(" BOX64_TRACE with 1 to enable x86_64 execution trace\n");
printf(" or with XXXXXX-YYYYYY to enable x86_64 execution trace only between address\n");
printf(" or with FunctionName to enable x86_64 execution trace only in one specific function\n");
- printf(" use BOX64_TRACE_INIT instead of BOX_TRACE to start trace before init of Libs and main program\n\t (function name will probably not work then)\n");
+ printf(" use BOX64_TRACE_INIT instead of BOX64_TRACE to start trace before init of Libs and main program\n\t (function name will probably not work then)\n");
printf(" BOX64_TRACE_EMM with 1 to enable dump of MMX registers along with regular registers\n");
printf(" BOX64_TRACE_XMM with 1 to enable dump of SSE registers along with regular registers\n");
printf(" BOX64_TRACE_COLOR with 1 to enable detection of changed general register values\n");
@@ -964,17 +1092,17 @@ void PrintHelp() {
printf(" BOX64_DYNAREC_TRACE with 0/1 to disable or enable Trace on generated code too\n");
#endif
#endif
- printf(" BOX64_TRACE_FILE with FileName to redirect logs in a file (or stderr to use stderr instead of stdout)");
+ printf(" BOX64_TRACE_FILE with FileName to redirect logs in a file (or stderr to use stderr instead of stdout)\n");
printf(" BOX64_DLSYM_ERROR with 1 to log dlsym errors\n");
printf(" BOX64_LOAD_ADDR=0xXXXXXX try to load at 0xXXXXXX main binary (if binary is a PIE)\n");
printf(" BOX64_NOSIGSEGV=1 to disable handling of SigSEGV\n");
- printf(" BOX64_NOSIGILL=1 to disable handling of SigILL\n");
+ printf(" BOX64_NOSIGILL=1 to disable handling of SigILL\n");
printf(" BOX64_SHOWSEGV=1 to show Segfault signal even if a signal handler is present\n");
- printf(" BOX64_X11THREADS=1 to call XInitThreads when loading X11 (for old Loki games with Loki_Compat lib)");
+ printf(" BOX64_X11THREADS=1 to call XInitThreads when loading X11 (for old Loki games with Loki_Compat lib)\n");
printf(" BOX64_LIBGL=libXXXX set the name (and optionnally full path) for libGL.so.1\n");
printf(" BOX64_LD_PRELOAD=XXXX[:YYYYY] force loading XXXX (and YYYY...) libraries with the binary\n");
- printf(" BOX64_ALLOWMISSINGLIBS with 1 to allow one to continue even if a lib is missing (unadvised, will probably crash later)\n");
- printf(" BOX64_PREFER_EMULATED=1 to prefer emulated libs first (execpt for glibc, alsa, pulse, GL, vulkan and X11\n");
+ printf(" BOX64_ALLOWMISSINGLIBS with 1 to allow one to continue even if a lib is missing (unadvised, will probably crash later)\n");
+ printf(" BOX64_PREFER_EMULATED=1 to prefer emulated libs first (execpt for glibc, alsa, pulse, GL, vulkan and X11)\n");
printf(" BOX64_PREFER_WRAPPED if box64 will use wrapped libs even if the lib is specified with absolute path\n");
printf(" BOX64_CRASHHANDLER=0 to not use a dummy crashhandler lib\n");
printf(" BOX64_NOPULSE=1 to disable the loading of pulseaudio libs\n");
@@ -985,6 +1113,15 @@ void PrintHelp() {
printf(" BOX64_JITGDB with 1 to launch \"gdb\" when a segfault is trapped, attached to the offending process\n");
}
+void PrintHelp() {
+ printf("This is Box64, The Linux x86_64 emulator with a twist\n");
+ printf("\nUsage is 'box64 [options] path/to/software [args]' to launch x86_64 software.\n");
+ printf(" options are:\n");
+ printf(" '-v'|'--version' to print box64 version and quit\n");
+ printf(" '-h'|'--help' to print this and quit\n");
+ printf(" '-f'|'--flags' to print box64 flags and quit\n");
+}
+
void addNewEnvVar(const char* s)
{
if(!s)
@@ -1023,12 +1160,18 @@ void LoadEnvVars(box64context_t *context)
}
// check BOX64_LD_LIBRARY_PATH and load it
LoadEnvPath(&context->box64_ld_lib, ".:lib:lib64:x86_64:bin64:libs64", "BOX64_LD_LIBRARY_PATH");
+ #ifndef TERMUX
if(FileExist("/lib/x86_64-linux-gnu", 0))
AddPath("/lib/x86_64-linux-gnu", &context->box64_ld_lib, 1);
if(FileExist("/usr/lib/x86_64-linux-gnu", 0))
AddPath("/usr/lib/x86_64-linux-gnu", &context->box64_ld_lib, 1);
if(FileExist("/usr/x86_64-linux-gnu/lib", 0))
AddPath("/usr/x86_64-linux-gnu/lib", &context->box64_ld_lib, 1);
+ #else
+ //TODO: Add Termux Library Path - Lily
+ if(FileExist("/data/data/com.termux/files/usr/lib/x86_64-linux-gnu", 0))
+ AddPath("/data/data/com.termux/files/usr/lib/x86_64-linux-gnu", &context->box64_ld_lib, 1);
+ #endif
if(getenv("LD_LIBRARY_PATH"))
PrependList(&context->box64_ld_lib, getenv("LD_LIBRARY_PATH"), 1); // in case some of the path are for x86 world
if(getenv("BOX64_EMULATED_LIBS")) {
@@ -1058,19 +1201,25 @@ void LoadEnvVars(box64context_t *context)
if(getenv("BOX64_X87_NO80BITS")) {
if (strcmp(getenv("BOX64_X87_NO80BITS"), "1")==0) {
box64_x87_no80bits = 1;
- printf_log(LOG_INFO, "BOX64: all 80bits x87 long double will be handle as double\n");
+ printf_log(LOG_INFO, "BOX64: All 80bits x87 long double will be handle as double\n");
+ }
+ }
+ if(getenv("BOX64_SYNC_ROUNDING")) {
+ if (strcmp(getenv("BOX64_SYNC_ROUNDING"), "1")==0) {
+ box64_sync_rounding = 1;
+ printf_log(LOG_INFO, "BOX64: Rouding mode with be synced with fesetround/fegetround\n");
}
}
if(getenv("BOX64_PREFER_WRAPPED")) {
if (strcmp(getenv("BOX64_PREFER_WRAPPED"), "1")==0) {
box64_prefer_wrapped = 1;
- printf_log(LOG_INFO, "BOX64: Prefer Wrapped libs\n");
+ printf_log(LOG_INFO, "BOX64: Prefering Wrapped libs\n");
}
}
if(getenv("BOX64_PREFER_EMULATED")) {
if (strcmp(getenv("BOX64_PREFER_EMULATED"), "1")==0) {
box64_prefer_emulated = 1;
- printf_log(LOG_INFO, "BOX64: Prefer Emulated libs\n");
+ printf_log(LOG_INFO, "BOX64: Prefering Emulated libs\n");
}
}
@@ -1108,7 +1257,7 @@ void LoadEnvVars(box64context_t *context)
if(my_context->x64trace) {
printf_log(LOG_INFO, "Initializing Zydis lib\n");
if(InitX64Trace(my_context)) {
- printf_log(LOG_INFO, "Zydis init failed, no x86 trace activated\n");
+ printf_log(LOG_INFO, "Zydis init failed. No x86 trace activated\n");
context->x64trace = 0;
}
}
@@ -1140,7 +1289,7 @@ void setupTraceInit()
SetTraceEmu(s_trace_start, s_trace_end);
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end);
} else {
- printf_log(LOG_NONE, "Warning, symbol to trace (\"%s\") not found, disabling trace\n", p);
+ printf_log(LOG_NONE, "Warning, Symbol to trace (\"%s\") not found, Disabling trace\n", p);
SetTraceEmu(0, 100); // disabling trace, mostly
}
}
@@ -1177,14 +1326,14 @@ void setupTrace()
}
}
} else {
- if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+ if (my_context->elfs && GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
SetTraceEmu(s_trace_start, s_trace_end);
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end);
- } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+ } else if(my_context->elfs && GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
SetTraceEmu(s_trace_start, s_trace_end);
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end);
} else {
- printf_log(LOG_NONE, "Warning, symbol to trace (\"%s\") not found, trying to set trace later\n", p);
+ printf_log(LOG_NONE, "Warning, Symbol to trace (\"%s\") not found. Trying to set trace later\n", p);
SetTraceEmu(0, 1); // disabling trace, mostly
if(trace_func)
box_free(trace_func);
@@ -1200,14 +1349,14 @@ void endBox64()
{
if(!my_context || box64_quit)
return;
-
+
+ // then call all the fini
+ box64_quit = 1;
endMallocHook();
x64emu_t* emu = thread_get_emu();
// atexit first
printf_log(LOG_DEBUG, "Calling atexit registered functions (exiting box64)\n");
CallAllCleanup(emu);
- // then call all the fini
- box64_quit = 1;
printf_log(LOG_DEBUG, "Calling fini for all loaded elfs and unload native libs\n");
RunElfFini(my_context->elfs[0], emu);
FreeLibrarian(&my_context->local_maplib, emu); // unload all libs
@@ -1261,6 +1410,10 @@ void endBox64()
box_free(box64_libGL);
box64_libGL = NULL;
}
+ if(box64_custom_gstreamer) {
+ box_free(box64_custom_gstreamer);
+ box64_custom_gstreamer = NULL;
+ }
}
@@ -1272,8 +1425,14 @@ static void free_contextargv()
static void load_rcfiles()
{
+ #ifndef TERMUX
if(FileExist("/etc/box64.box64rc", IS_FILE))
LoadRCFile("/etc/box64.box64rc");
+ #else
+ if(FileExist("/data/data/com.termux/files/usr/etc/box64.box64rc", IS_FILE))
+ LoadRCFile("/data/data/com.termux/files/usr/etc/box64.box64rc");
+ #endif
+
else
LoadRCFile(NULL); // load default rcfile
char* p = getenv("HOME");
@@ -1286,16 +1445,19 @@ static void load_rcfiles()
}
}
-void pressure_vessel(int argc, const char** argv, int nextarg);
+void pressure_vessel(int argc, const char** argv, int nextarg, const char* prog);
extern char** environ;
int main(int argc, const char **argv, char **env) {
init_malloc_hook();
init_auxval(argc, argv, environ?environ:env);
// trying to open and load 1st arg
if(argc==1) {
- PrintBox64Version();
+ /*PrintBox64Version();
PrintHelp();
- return 1;
+ return 1;*/
+ printf("BOX64: Missing operand after 'box64'\n");
+ printf("See 'box64 --help' for more information.\n");
+ exit(0);
}
if(argc>1 && !strcmp(argv[1], "/usr/bin/gdb") && getenv("BOX64_TRACE_FILE"))
exit(0);
@@ -1319,11 +1481,11 @@ int main(int argc, const char **argv, char **env) {
bashpath = p;
printf_log(LOG_INFO, "Using bash \"%s\"\n", bashpath);
} else {
- printf_log(LOG_INFO, "the x86_64 bash \"%s\" is not an x86_64 binary\n", p);
+ printf_log(LOG_INFO, "The x86_64 bash \"%s\" is not an x86_64 binary.\n", p);
}
}
}
-
+
const char* prog = argv[1];
int nextarg = 1;
// check if some options are passed
@@ -1336,22 +1498,26 @@ int main(int argc, const char **argv, char **env) {
PrintHelp();
exit(0);
}
+ if(!strcmp(prog, "-f") || !strcmp(prog, "--flags")) {
+ PrintFlags();
+ exit(0);
+ }
// other options?
if(!strcmp(prog, "--")) {
prog = argv[++nextarg];
break;
}
- printf("Warning, unrecognized option '%s'\n", prog);
+ printf("Warning, Unrecognized option '%s'\n", prog);
prog = argv[++nextarg];
}
if(!prog || nextarg==argc) {
- printf("Box64: nothing to run\n");
+ printf("BOX64: Nothing to run\n");
exit(0);
}
if(!box64_nobanner)
PrintBox64Version();
// precheck, for win-preload
- if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))
+ if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))
|| strstr(prog, "wine64-preloader")==(prog+strlen(prog)-strlen("wine64-preloader"))) {
// wine-preloader detecter, skipping it if next arg exist and is an x86 binary
int x64 = (nextarg<argc)?FileIsX64ELF(argv[nextarg]):0;
@@ -1364,18 +1530,18 @@ int main(int argc, const char **argv, char **env) {
#if 1
// pre-check for pressure-vessel-wrap
if(strstr(prog, "pressure-vessel-wrap")==(prog+strlen(prog)-strlen("pressure-vessel-wrap"))) {
- // pressure-vessel-wrap detecter, skipping it and all -- args until "--" if needed
printf_log(LOG_INFO, "BOX64: pressure-vessel-wrap detected\n");
- pressure_vessel(argc, argv, nextarg+1);
+ pressure_vessel(argc, argv, nextarg+1, prog);
}
#endif
int ld_libs_args = -1;
+ int is_custom_gstreamer = 0;
// check if this is wine
if(!strcmp(prog, "wine64")
|| !strcmp(prog, "wine64-development")
|| !strcmp(prog, "wine")
- || (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine"), "/wine"))
- || (strlen(prog)>7 && !strcmp(prog+strlen(prog)-strlen("/wine64"), "/wine64"))) {
+ || (strrchr(prog, '/') && !strcmp(strrchr(prog,'/'), "/wine"))
+ || (strrchr(prog, '/') && !strcmp(strrchr(prog,'/'), "/wine64"))) {
const char* prereserve = getenv("WINEPRELOADRESERVE");
printf_log(LOG_INFO, "BOX64: Wine64 detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
if(wine_preloaded)
@@ -1391,10 +1557,24 @@ int main(int argc, const char **argv, char **env) {
}
}
box64_wine = 1;
- } else
+ // check if it's proton, with it's custom gstreamer build, to disable gtk3 loading
+ char tmp[strlen(prog)+100];
+ strcpy(tmp, prog);
+ char* pp = strrchr(tmp, '/');
+ if(pp) {
+ *pp = '\0'; // remove the wine binary call
+ strcat(tmp, "/../lib64/gstreamer-1.0");
+ // check if it exist
+ if(FileExist(tmp, 0)) {
+ //printf_log(LOG_INFO, "BOX64: Custom gstreamer detected, disable gtk wrapping\n");
+ //box64_nogtk = 1;
+ //is_custom_gstreamer = 1;
+ box64_custom_gstreamer = box_strdup(tmp);
+ }
+ }
+ } else if(strstr(prog, "ld-musl-x86_64.so.1")) {
// check if ld-musl-x86_64.so.1 is used
- if(strstr(prog, "ld-musl-x86_64.so.1")) {
- printf_log(LOG_INFO, "BOX64: ld-musl detected, trying to workaround and use system ld-linux\n");
+ printf_log(LOG_INFO, "BOX64: ld-musl detected. Trying to workaround and use system ld-linux\n");
box64_musl = 1;
// skip ld-musl and go through args unti "--" is found, handling "--library-path" to add some libs to BOX64_LD_LIBRARY
++nextarg;
@@ -1424,6 +1604,8 @@ int main(int argc, const char **argv, char **env) {
// Append ld_list if it exist
if(ld_libs_args!=-1)
PrependList(&my_context->box64_ld_lib, argv[ld_libs_args], 1);
+ if(is_custom_gstreamer)
+ AddPath("libwayland-client.so.0", &my_context->box64_emulated_libs, 0);
my_context->box64path = ResolveFile(argv[0], &my_context->box64_path);
// prepare all other env. var
@@ -1442,7 +1624,7 @@ int main(int argc, const char **argv, char **env) {
char* p = getenv("BOX64_LD_PRELOAD");
ParseList(p, &ld_preload, 0);
if (ld_preload.size && box64_log) {
- printf_log(LOG_INFO, "BOX64 try to Preload ");
+ printf_log(LOG_INFO, "BOX64 trying to Preload ");
for (int i=0; i<ld_preload.size; ++i)
printf_log(LOG_INFO, "%s ", ld_preload.paths[i]);
printf_log(LOG_INFO, "\n");
@@ -1460,13 +1642,16 @@ int main(int argc, const char **argv, char **env) {
box64_tcmalloc_minimal = 1; // it seems Address Sanitizer doesn't handle dlsym'd malloc very well
ParseList(p, &ld_preload, 0);
if (ld_preload.size && box64_log) {
- printf_log(LOG_INFO, "BOX64 try to Preload ");
+ printf_log(LOG_INFO, "BOX64 trying to Preload ");
for (int i=0; i<ld_preload.size; ++i)
printf_log(LOG_INFO, "%s ", ld_preload.paths[i]);
printf_log(LOG_INFO, "\n");
}
}
}
+ // print PATH and LD_LIB used
+ PrintCollection(&my_context->box64_ld_lib, "BOX64 LIB PATH");
+ PrintCollection(&my_context->box64_path, "BOX64 BIN PATH");
// lets build argc/argv stuff
printf_log(LOG_INFO, "Looking for %s\n", prog);
my_context->argv[0] = ResolveFile(prog, &my_context->box64_path);
@@ -1486,11 +1671,15 @@ int main(int argc, const char **argv, char **env) {
else
++prgname;
if(box64_wine) {
- AddPath("libdl.so.2", &ld_preload, 0);
+ #ifdef ANDROID
+ AddPath("libdl.so", &ld_preload, 0);
+ #else
+ AddPath("libdl.so.2", &ld_preload, 0);
+ #endif
}
// special case for zoom
if(strstr(prgname, "zoom")==prgname) {
- printf_log(LOG_INFO, "Zoom detected, trying to use system libturbojpeg if possible\n");
+ printf_log(LOG_INFO, "Zoom detected, Trying to use system libturbojpeg if possible\n");
box64_zoom = 1;
}
// special case for bash (add BOX86_NOBANNER=1 if not there)
@@ -1535,17 +1724,30 @@ int main(int argc, const char **argv, char **env) {
my_context->argc++;
}
}
+ if(box64_inprocessgpu)
+ {
+ // check if in-process-gpu is already there
+ int there = 0;
+ for(int i=1; i<my_context->argc && !there; ++i)
+ if(!strcmp(my_context->argv[i], "--in-process-gpu"))
+ there = 1;
+ if(!there) {
+ my_context->argv = (char**)box_realloc(my_context->argv, (my_context->argc+1)*sizeof(char*));
+ my_context->argv[my_context->argc] = box_strdup("--in-process-gpu");
+ my_context->argc++;
+ }
+ }
// check if file exist
if(!my_context->argv[0] || !FileExist(my_context->argv[0], IS_FILE)) {
- printf_log(LOG_NONE, "Error: file is not found (check BOX64_PATH)\n");
+ printf_log(LOG_NONE, "Error: File is not found. (check BOX64_PATH)\n");
free_contextargv();
FreeBox64Context(&my_context);
FreeCollection(&ld_preload);
return -1;
}
if(!FileExist(my_context->argv[0], IS_FILE|IS_EXECUTABLE)) {
- printf_log(LOG_NONE, "Error: %s is not an executable file\n", my_context->argv[0]);
+ printf_log(LOG_NONE, "Error: %s is not an executable file.\n", my_context->argv[0]);
free_contextargv();
FreeBox64Context(&my_context);
FreeCollection(&ld_preload);
@@ -1567,7 +1769,7 @@ int main(int argc, const char **argv, char **env) {
if(!elf_header) {
int x86 = my_context->box86path?FileIsX86ELF(my_context->fullpath):0;
int script = my_context->bashpath?FileIsShell(my_context->fullpath):0;
- printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch %s instead\n", my_context->fullpath, x86?"using box86":(script?"using bash":"natively"));
+ printf_log(LOG_NONE, "Error: Reading elf header of %s, Try to launch %s instead\n", my_context->fullpath, x86?"using box86":(script?"using bash":"natively"));
fclose(f);
FreeCollection(&ld_preload);
int ret;
@@ -1599,37 +1801,26 @@ int main(int argc, const char **argv, char **env) {
AddElfHeader(my_context, elf_header);
if(CalcLoadAddr(elf_header)) {
- printf_log(LOG_NONE, "Error: reading elf header of %s\n", my_context->fullpath);
- fclose(f);
+ printf_log(LOG_NONE, "Error: Reading elf header of %s\n", my_context->fullpath);
+ FreeElfHeader(&elf_header);
free_contextargv();
FreeBox64Context(&my_context);
FreeCollection(&ld_preload);
return -1;
}
- // allocate memory
- if(AllocElfMemory(my_context, elf_header, 1)) {
- printf_log(LOG_NONE, "Error: allocating memory for elf %s\n", my_context->fullpath);
- fclose(f);
- free_contextargv();
- FreeBox64Context(&my_context);
- FreeCollection(&ld_preload);
- return -1;
- }
- // Load elf into memory
- if(LoadElfMemory(f, my_context, elf_header)) {
- printf_log(LOG_NONE, "Error: loading in memory elf %s\n", my_context->fullpath);
- fclose(f);
+ // allocate memory and load elf
+ if(AllocLoadElfMemory(my_context, elf_header, 1)) {
+ printf_log(LOG_NONE, "Error: Loading elf %s\n", my_context->fullpath);
+ FreeElfHeader(&elf_header);
free_contextargv();
FreeBox64Context(&my_context);
FreeCollection(&ld_preload);
return -1;
}
- // can close the file now
- fclose(f);
if(ElfCheckIfUseTCMallocMinimal(elf_header)) {
if(!box64_tcmalloc_minimal) {
// need to reload with tcmalloc_minimal as a LD_PRELOAD!
- printf_log(LOG_INFO, "BOX64: tcmalloc_minimal.so.4 used, reloading box64 with the lib preladed\n");
+ printf_log(LOG_INFO, "BOX64: tcmalloc_minimal.so.4 used. Reloading box64 with the lib preladed\n");
// need to get a new envv variable. so first count it and check if LD_PRELOAD is there
int preload=(getenv("LD_PRELOAD"))?1:0;
int nenv = 0;
@@ -1667,7 +1858,7 @@ int main(int argc, const char **argv, char **env) {
while(argv[narg]) {newargv[narg] = box_strdup(argv[narg]); narg++;}
// launch with new env...
if(execve(newargv[0], newargv, newenv)<0)
- printf_log(LOG_NONE, "Failed to relaunch, error is %d/%s\n", errno, strerror(errno));
+ printf_log(LOG_NONE, "Failed to relaunch. Error is %d/%s\n", errno, strerror(errno));
} else {
printf_log(LOG_INFO, "BOX64: Using tcmalloc_minimal.so.4, and it's in the LD_PRELOAD command\n");
}
@@ -1701,9 +1892,12 @@ int main(int argc, const char **argv, char **env) {
for(int i=nextarg; i<argc; ++i)
argv[i] -= diff; // adjust strings
}
+ box64_isglibc234 = GetNeededVersionForLib(elf_header, "libc.so.6", "GLIBC_2.34");
+ if(box64_isglibc234)
+ printf_log(LOG_DEBUG, "Program linked with GLIBC 2.34+\n");
// get and alloc stack size and align
if(CalcStackSize(my_context)) {
- printf_log(LOG_NONE, "Error: allocating stack\n");
+ printf_log(LOG_NONE, "Error: Allocating stack\n");
free_contextargv();
FreeBox64Context(&my_context);
FreeCollection(&ld_preload);
@@ -1726,9 +1920,6 @@ int main(int argc, const char **argv, char **env) {
// export symbols
AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header);
- box64_isglibc234 = GetVersionIndice(elf_header, "GLIBC_2.34")?1:0;
- if(box64_isglibc234)
- printf_log(LOG_DEBUG, "Program linked with GLIBC 2.34+\n");
if(wine_preloaded) {
uintptr_t wineinfo = FindSymbol(GetMapSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL);
if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL);
@@ -1750,7 +1941,7 @@ int main(int argc, const char **argv, char **env) {
needed_libs_t* tmp = new_neededlib(1);
tmp->names[0] = ld_preload.paths[i];
if(AddNeededLib(my_context->maplib, 0, 0, tmp, elf_header, my_context, emu)) {
- printf_log(LOG_INFO, "Warning, cannot pre-load of %s\n", tmp->names[0]);
+ printf_log(LOG_INFO, "Warning, cannot pre-load %s\n", tmp->names[0]);
RemoveNeededLib(my_context->maplib, 0, tmp, my_context, emu);
} else {
for(int j=0; j<tmp->size; ++j)
@@ -1762,14 +1953,14 @@ int main(int argc, const char **argv, char **env) {
FreeCollection(&ld_preload);
// Call librarian to load all dependant elf
if(LoadNeededLibs(elf_header, my_context->maplib, 0, 0, my_context, emu)) {
- printf_log(LOG_NONE, "Error: loading needed libs in elf %s\n", my_context->argv[0]);
+ printf_log(LOG_NONE, "Error: Loading needed libs in elf %s\n", my_context->argv[0]);
FreeBox64Context(&my_context);
return -1;
}
// reloc...
printf_log(LOG_DEBUG, "And now export symbols / relocation for %s...\n", ElfName(elf_header));
if(RelocateElf(my_context->maplib, NULL, 0, elf_header)) {
- printf_log(LOG_NONE, "Error: relocating symbols in elf %s\n", my_context->argv[0]);
+ printf_log(LOG_NONE, "Error: Relocating symbols in elf %s\n", my_context->argv[0]);
FreeBox64Context(&my_context);
return -1;
}
@@ -1801,7 +1992,7 @@ int main(int argc, const char **argv, char **env) {
// Get EAX
int ret = GetEAX(emu);
printf_log(LOG_DEBUG, "Emulation finished, EAX=%d\n", ret);
-
+ endBox64();
#ifdef HAVE_TRACE
if(trace_func) {
box_free(trace_func);
diff --git a/src/mallochook.c b/src/mallochook.c
index 885e38c..52a09c7 100644
--- a/src/mallochook.c
+++ b/src/mallochook.c
@@ -41,7 +41,7 @@
This is the Exterminate strategy implementation
*/
-
+#ifndef ANDROID
#include "bridge.h"
#include "wrapper.h"
@@ -131,13 +131,6 @@ typedef void* (*pFpLp_t)(void*, size_t, void*);
typedef void (*vFpLL_t)(void*, size_t, size_t);
typedef void* (*pFpLLp_t)(void*, size_t, size_t, void*);
-#ifdef ANDROID
-void*(*__libc_malloc)(size_t) = NULL;
-void*(*__libc_realloc)(size_t, void*) = NULL;
-void*(*__libc_calloc)(size_t, size_t) = NULL;
-void (*__libc_free)(void*) = NULL;
-void*(*__libc_memalign)(size_t, size_t) = NULL;
-#endif
size_t(*box_malloc_usable_size)(void*) = NULL;
int GetTID();
@@ -200,11 +193,11 @@ EXPORT void* malloc(size_t l)
EXPORT void free(void* p)
{
- if(malloc_hack_2 && FREE && p) {
+ if(malloc_hack_2 && p) {
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
+ if(real_free && FREE)
RunFunctionFmt(real_free, "p", p);
return;
}
@@ -225,7 +218,7 @@ EXPORT void* realloc(void* p, size_t s)
if(malloc_hack_2)
if(getMmapped((uintptr_t)p) || (!p && ALLOC && real_realloc)) {
void* ret = p;
- if(real_realloc) {
+ if(real_realloc && ALLOC) {
ret = (void*)RunFunctionFmt(real_realloc, "pL", p, s);
} else {
// found! Will realloc using regular malloc then copy from old address as much as possible, but need to check size first
@@ -235,7 +228,7 @@ EXPORT void* realloc(void* p, size_t s)
memcpy(ret, p, s);
printf_log(LOG_DEBUG, " -> %p (copied %zu from old)\n", ret, s);
// Mmaped, free with original function
- if(real_free)
+ if(real_free && FREE)
RunFunctionFmt(real_free, "p", p);
}
return ret;
@@ -291,11 +284,11 @@ EXPORT void* pvalloc(size_t size)
EXPORT void cfree(void* p)
{
- if(malloc_hack_2 && FREE && p) {
+ if(malloc_hack_2 && p) {
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
+ if(real_free && FREE)
RunFunctionFmt(real_free, "p", p);
return;
}
@@ -464,11 +457,12 @@ EXPORT void my__ZdlPvRKSt9nothrow_t(void* p, void* n) //operator delete(void*,
EXPORT void my__ZdaPvSt11align_val_tRKSt9nothrow_t(void* p, size_t align, void* n) //operator delete[](void*, std::align_val_t, std::nothrow_t const&)
{
if(malloc_hack_2 && p) {
+ printf_log(LOG_INFO, "%04d|Malloc_Hack_2: my__ZdaPvSt11align_val_tRKSt9nothrow_t(%p, %d, %p)\n", GetTID(), p, align, n);
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
- RunFunctionFmt(real_free, "p", p);
+ if(real__ZdaPvSt11align_val_tRKSt9nothrow_t)
+ RunFunctionFmt(real__ZdaPvSt11align_val_tRKSt9nothrow_t, "p", p);
return;
}
}
@@ -481,8 +475,8 @@ EXPORT void my__ZdlPvmSt11align_val_t(void* p, size_t sz, size_t align) //oper
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
- RunFunctionFmt(real_free, "p", p);
+ if(real__ZdlPvmSt11align_val_t)
+ RunFunctionFmt(real__ZdlPvmSt11align_val_t, "p", p);
return;
}
}
@@ -495,8 +489,8 @@ EXPORT void my__ZdaPvRKSt9nothrow_t(void* p, void* n) //operator delete[](void
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
- RunFunctionFmt(real_free, "p", p);
+ if(real__ZdaPvRKSt9nothrow_t)
+ RunFunctionFmt(real__ZdaPvRKSt9nothrow_t, "p", p);
return;
}
}
@@ -509,8 +503,8 @@ EXPORT void my__ZdaPvSt11align_val_t(void* p, size_t align) //operator delete[
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
- RunFunctionFmt(real_free, "p", p);
+ if(real__ZdaPvSt11align_val_t)
+ RunFunctionFmt(real__ZdaPvSt11align_val_t, "p", p);
return;
}
}
@@ -523,8 +517,8 @@ EXPORT void my__ZdlPvSt11align_val_t(void* p, size_t align) //operator delete(
if(getMmapped((uintptr_t)p)) {
printf_log(LOG_DEBUG, "%04d|Malloc_Hack_2: not freeing %p\n", GetTID(), p);
// Mmaped, free with original function
- if(real_free)
- RunFunctionFmt(real_free, "p", p);
+ if(real__ZdlPvSt11align_val_t)
+ RunFunctionFmt(real__ZdlPvSt11align_val_t, "p", p);
return;
}
}
@@ -779,39 +773,51 @@ static void addRelocJmp(void* offs, void* where, size_t size, const char* name,
void checkHookedSymbols(elfheader_t* h)
{
int hooked = 0;
+ int hooked_symtab = 0;
if(box64_malloc_hack==1)
return;
- for (size_t i=0; i<h->numDynSym && hooked<2; ++i) {
- const char * symname = h->DynStr+h->DynSym[i].st_name;
- int bind = ELF64_ST_BIND(h->DynSym[i].st_info);
- int type = ELF64_ST_TYPE(h->DynSym[i].st_info);
- int vis = h->DynSym[i].st_other&0x3;
- if((type==STT_FUNC)
- && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) {
- uintptr_t offs = h->DynSym[i].st_value + h->delta;
- size_t sz = h->DynSym[i].st_size;
- if(bind!=STB_LOCAL && bind!=STB_WEAK && sz>=sizeof(reloc_jmp_t)) {
- #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "__libc_" #A)) ++hooked;
- #define GO2(A, B)
- SUPER()
- #undef GO
- #undef GO2
- }
+ for (size_t i=0; i<h->numSymTab; ++i) {
+ int type = ELF64_ST_TYPE(h->SymTab[i].st_info);
+ if(type==STT_FUNC) {
+ const char * symname = h->StrTab+h->SymTab[i].st_name;
+ #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "__libc_" #A)) ++hooked;
+ #define GO2(A, B)
+ SUPER()
+ #undef GO
+ #undef GO2
}
}
+ if(hooked<2) {
+ for (size_t i=0; i<h->numDynSym && hooked<2; ++i) {
+ const char * symname = h->DynStr+h->DynSym[i].st_name;
+ int bind = ELF64_ST_BIND(h->DynSym[i].st_info);
+ int type = ELF64_ST_TYPE(h->DynSym[i].st_info);
+ int vis = h->DynSym[i].st_other&0x3;
+ if((type==STT_FUNC)
+ && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) {
+ uintptr_t offs = h->DynSym[i].st_value + h->delta;
+ size_t sz = h->DynSym[i].st_size;
+ if(bind!=STB_LOCAL && bind!=STB_WEAK && sz>=sizeof(reloc_jmp_t)) {
+ #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "__libc_" #A)) ++hooked;
+ #define GO2(A, B)
+ SUPER()
+ #undef GO
+ #undef GO2
+ }
+ }
+ }
+ } else
+ hooked_symtab = 1;
if(hooked<2)
return; // only redirect on lib that hooked / redefined the operators
- printf_log(LOG_INFO, "Redirecting overridden malloc%s function for %s\n", malloc_hack_2?" with hack":"", ElfName(h));
- for (size_t i=0; i<h->numDynSym; ++i) {
- const char * symname = h->DynStr+h->DynSym[i].st_name;
- int bind = ELF64_ST_BIND(h->DynSym[i].st_info);
- int type = ELF64_ST_TYPE(h->DynSym[i].st_info);
- int vis = h->DynSym[i].st_other&0x3;
- if((type==STT_FUNC)
- && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) {
- uintptr_t offs = h->DynSym[i].st_value + h->delta;
- size_t sz = h->DynSym[i].st_size;
- if(bind!=STB_LOCAL && bind!=STB_WEAK) {
+ printf_log(LOG_INFO, "Redirecting overridden malloc%s from %s function for %s\n", malloc_hack_2?" with hack":"", hooked_symtab?"symtab":"dynsym", ElfName(h));
+ if(hooked_symtab) {
+ for (size_t i=0; i<h->numSymTab; ++i) {
+ int type = ELF64_ST_TYPE(h->SymTab[i].st_info);
+ if(type==STT_FUNC) {
+ const char * symname = h->StrTab+h->SymTab[i].st_name;
+ uintptr_t offs = h->SymTab[i].st_value + h->delta;
+ size_t sz = h->SymTab[i].st_size;
#define GO(A, B) if(!strcmp(symname, "__libc_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "__libc_" #A, h, NULL);}
#define GO2(A, B)
SUPER()
@@ -824,6 +830,30 @@ void checkHookedSymbols(elfheader_t* h)
#undef GO2
}
}
+ } else {
+ for (size_t i=0; i<h->numDynSym; ++i) {
+ const char * symname = h->DynStr+h->DynSym[i].st_name;
+ int bind = ELF64_ST_BIND(h->DynSym[i].st_info);
+ int type = ELF64_ST_TYPE(h->DynSym[i].st_info);
+ int vis = h->DynSym[i].st_other&0x3;
+ if((type==STT_FUNC)
+ && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) {
+ uintptr_t offs = h->DynSym[i].st_value + h->delta;
+ size_t sz = h->DynSym[i].st_size;
+ if(bind!=STB_LOCAL && bind!=STB_WEAK) {
+ #define GO(A, B) if(!strcmp(symname, "__libc_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "__libc_" #A, h, NULL);}
+ #define GO2(A, B)
+ SUPER()
+ #undef GO
+ #undef GO2
+ #define GO(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h, &real_##A);}
+ #define GO2(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h, &real_##A);}
+ SUPER()
+ #undef GO
+ #undef GO2
+ }
+ }
+ }
}
if(box64_malloc_hack==2)
h->malloc_hook_2 = 1;
@@ -875,13 +905,6 @@ EXPORT int my___RML_open_factory(void* factory, void* server_version, int client
}
void init_malloc_hook() {
-#ifdef ANDROID
- __libc_malloc = dlsym(RTLD_NEXT, "malloc");
- __libc_realloc = dlsym(RTLD_NEXT, "realloc");
- __libc_calloc = dlsym(RTLD_NEXT, "calloc");
- __libc_free = dlsym(RTLD_NEXT, "free");
- __libc_memalign = dlsym(RTLD_NEXT, "memalign");
-#endif
box_malloc_usable_size = dlsym(RTLD_NEXT, "malloc_usable_size");
#if 0
#define GO(A, B)
@@ -892,4 +915,10 @@ void init_malloc_hook() {
#endif
}
-#undef SUPER \ No newline at end of file
+#undef SUPER
+#else//ANDROID
+void init_malloc_hook() {}
+void startMallocHook() {}
+void endMallocHook() {}
+void checkHookedSymbols(elfheader_t* h) {}
+#endif //!ANDROID \ No newline at end of file
diff --git a/src/rv64detect.c b/src/rv64detect.c
index 9976d1d..e1b3b40 100644
--- a/src/rv64detect.c
+++ b/src/rv64detect.c
@@ -11,7 +11,7 @@
// Detect RV64 extensions, by executing on of the opcode with a SIGILL signal handler
static sigjmp_buf sigbuf = {0};
-typedef void(*vFii_t)(int, int);
+typedef void(*vFiip_t)(int, int, void*);
static void detect_sigill(int sig)
{
siglongjmp(sigbuf, 1);
@@ -19,6 +19,7 @@ static void detect_sigill(int sig)
static int Check(void* block)
{
+ static uint64_t buf[2] = {0};
// Clear instruction cache
__clear_cache(block, block+box64_pagesize);
// Setup SIGILL signal handler
@@ -28,7 +29,7 @@ static int Check(void* block)
signal(SIGILL, old);
return 0;
}
- ((vFii_t)block)(0, 1);
+ ((vFiip_t)block)(0, 1, buf);
// done...
signal(SIGILL, old);
return 1;
@@ -43,6 +44,9 @@ void RV64_Detect_Function()
}
uint32_t* block;
#define EMIT(A) *block = (A); ++block
+
+ // Official extensions
+
// Test Zba with ADDUW
block = (uint32_t*)my_block;
ADDUW(A0, A0, A1);
@@ -64,7 +68,63 @@ void RV64_Detect_Function()
BR(xRA);
rv64_zbs = Check(my_block);
+ // THead vendor extensions
+
+ // Test XTheadBa with TH_ADDSL
+ block = (uint32_t*)my_block;
+ TH_ADDSL(A0, A0, A1, 1);
+ BR(xRA);
+ rv64_xtheadba = Check(my_block);
+
+ // Test XTheadBb with TH_SRRI
+ block = (uint32_t*)my_block;
+ TH_SRRI(A0, A1, 1);
+ BR(xRA);
+ rv64_xtheadbb = Check(my_block);
+
+ // Test XTheadBs with TH_TST
+ block = (uint32_t*)my_block;
+ TH_TST(A0, A1, 1);
+ BR(xRA);
+ rv64_xtheadbs = Check(my_block);
+
+ // Test XTheadCondMov with TH_MVEQZ
+ block = (uint32_t*)my_block;
+ TH_MVEQZ(A0, A0, A1);
+ BR(xRA);
+ rv64_xtheadcondmov = Check(my_block);
+
+ // Test XTheadMemIdx with TH_LBIA
+ block = (uint32_t*)my_block;
+ TH_LBIA(A0, A2, 1, 1);
+ BR(xRA);
+ rv64_xtheadmemidx = Check(my_block);
+
+ // Test XTheadMemPair with TH_LDD
+ block = (uint32_t*)my_block;
+ TH_LDD(A0, A1, A2, 0);
+ BR(xRA);
+ rv64_xtheadmempair = Check(my_block);
+
+ // Test XTheadFMemIdx with TH_FLRD
+ block = (uint32_t*)my_block;
+ TH_FLRD(A0, A2, xZR, 0);
+ BR(xRA);
+ rv64_xtheadfmemidx = Check(my_block);
+
+ // Test XTheadMac with TH_MULA
+ block = (uint32_t*)my_block;
+ TH_MULA(A0, A0, A1);
+ BR(xRA);
+ rv64_xtheadmac = Check(my_block);
+
+ // Test XTheadFmv with TH_FMV_X_HW
+ block = (uint32_t*)my_block;
+ TH_FMV_X_HW(A0, A1);
+ BR(xRA);
+ rv64_xtheadfmv = Check(my_block);
+
// Finish
// Free the memory my_block
munmap(my_block, box64_pagesize);
-} \ No newline at end of file
+}
diff --git a/src/steam.c b/src/steam.c
index 4d48cae..b221b54 100644
--- a/src/steam.c
+++ b/src/steam.c
@@ -9,35 +9,51 @@
#include "box64context.h"
#include "fileutils.h"
-void pressure_vessel(int argc, const char** argv, int nextarg)
+#ifndef MAX_PATH
+#define MAX_PATH 4096
+#endif
+
+void pressure_vessel(int argc, const char** argv, int nextarg, const char* prog)
{
// skip all the parameter, but parse some of them
+ const char* runtime = getenv("PRESSURE_VESSEL_RUNTIME");
+ int ld_lib_path = 0;
+ // look for the comand first
+ const char* cmd = argv[nextarg];
+ int i = 0;
+ while(cmd[0]=='-' && cmd[1]=='-') cmd=argv[nextarg+(++i)];
+ int is_usr = (cmd && strlen(cmd)>5 && strstr(cmd, "/usr/")==cmd)?1:0;
if(argv[nextarg][0]=='-' && argv[nextarg][1]=='-')
while(argv[nextarg][0]=='-' && argv[nextarg][1]=='-') {
if(strstr(argv[nextarg], "--env-if-host=PRESSURE_VESSEL_APP_LD_LIBRARY_PATH=")==argv[nextarg]) {
- // transform RESSURE_VESSEL_APP_LD_LIBRARY_PATH to BOX86_ / BOX64_ LD_LIBRARY_PATH
- char tmp[strlen(argv[nextarg])];
- strcpy(tmp, "");
- strcat(tmp, argv[nextarg]+strlen("--env-if-host=PRESSURE_VESSEL_APP_"));
- char *p = strchr(tmp, '=');
- *p ='\0'; ++p;
- setenv(tmp, p, 1);
- printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
+ if(is_usr) {
+ // transform RESSURE_VESSEL_APP_LD_LIBRARY_PATH to BOX86_ / BOX64_ LD_LIBRARY_PATH
+ char tmp[strlen(argv[nextarg])+(runtime?(strlen(runtime)+1):0)];
+ strcpy(tmp, "");
+ strcat(tmp, argv[nextarg]+strlen("--env-if-host=PRESSURE_VESSEL_APP_"));
+ char *p = strchr(tmp, '=');
+ *p ='\0'; ++p;
+ ld_lib_path = 1;
+ setenv(tmp, p, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
+ }
} else if(strstr(argv[nextarg], "--env-if-host=STEAM_RUNTIME_LIBRARY_PATH=")==argv[nextarg]) {
- // transform RESSURE_VESSEL_APP_LD_LIBRARY_PATH to BOX86_ / BOX64_ LD_LIBRARY_PATH
- char tmp[strlen(argv[nextarg])+150];
- strcpy(tmp, "BOX86_LD_LIBRARY_PATH=/lib/box86:/usr/lib/box86:/lib/i386-linux-gnu:/usr/lib/i386-linux-gnu:/usr/lib/i686-pc-linux-gnu:/usr/lib32:");
- strcat(tmp, argv[nextarg]+strlen("--env-if-host=STEAM_RUNTIME_LIBRARY_PATH="));
- char *p = strchr(tmp, '=');
- *p ='\0'; ++p;
- setenv(tmp, p, 1);
- printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
- strcpy(tmp, "BOX64_LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:");
- strcat(tmp, argv[nextarg]+strlen("--env-if-host=STEAM_RUNTIME_LIBRARY_PATH="));
- p = strchr(tmp, '=');
- *p ='\0'; ++p;
- setenv(tmp, p, 1);
- printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
+ if(is_usr) {
+ // transform RESSURE_VESSEL_APP_LD_LIBRARY_PATH to BOX86_ / BOX64_ LD_LIBRARY_PATH
+ char tmp[strlen(argv[nextarg])+150];
+ strcpy(tmp, "BOX86_LD_LIBRARY_PATH=/lib/box86:/usr/lib/box86:/lib/i386-linux-gnu:/usr/lib/i386-linux-gnu:/usr/lib/i686-pc-linux-gnu:/usr/lib32:");
+ strcat(tmp, argv[nextarg]+strlen("--env-if-host=STEAM_RUNTIME_LIBRARY_PATH="));
+ char *p = strchr(tmp, '=');
+ *p ='\0'; ++p;
+ setenv(tmp, p, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
+ strcpy(tmp, "BOX64_LD_LIBRARY_PATH=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:");
+ strcat(tmp, argv[nextarg]+strlen("--env-if-host=STEAM_RUNTIME_LIBRARY_PATH="));
+ p = strchr(tmp, '=');
+ *p ='\0'; ++p;
+ setenv(tmp, p, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", tmp, p);
+ }
} else if(!strcmp(argv[nextarg], "--")) {
printf_log(LOG_DEBUG, "End of pressure-vessel-wrap parameters\n");
}else {
@@ -45,8 +61,69 @@ void pressure_vessel(int argc, const char** argv, int nextarg)
}
++nextarg;
}
+ if(runtime) {
+ char sniper[MAX_PATH] = {0};
+ // build sniper path
+ strcpy(sniper, prog);
+ char* p = strrchr(sniper, '/');
+ if(p) {
+ *p = '\0';
+ strcat(sniper, "/../../");
+ strcat(sniper, runtime);
+ } else {
+ printf_log(LOG_INFO, "Warning, could not guess sniper runtime path\n");
+ strcpy(sniper, runtime); // it's wrong...
+ }
+ printf_log(LOG_DEBUG, "pressure-vessel sniper env: %s\n", sniper);
+ // TODO: read metadata from sniper folder and analyse [Environment] section
+ strcat(sniper, "/files"); // this is the sniper root
+ // do LD_LIBRARY_PATH
+ {
+ char tmp[MAX_PATH*4] = {0};
+ // prepare folders, using ldconfig
+ snprintf(tmp, sizeof(tmp), "ldconfig -i -n %s/lib/x86_64-linux-gnu", sniper);
+ if(system(tmp)<0) printf_log(LOG_INFO, "%s failed\n", tmp);
+ snprintf(tmp, sizeof(tmp), "ldconfig -i -n %s/lib/i386-linux-gnu", sniper);
+ if(system(tmp)<0) printf_log(LOG_INFO, "%s failed\n", tmp);
+ snprintf(tmp, sizeof(tmp), "ldconfig -i -n %s/lib", sniper);
+ if(system(tmp)<0) printf_log(LOG_INFO, "%s failed\n", tmp);
+ snprintf(tmp, sizeof(tmp), "ldconfig -i -n %s/lib64", sniper);
+ if(system(tmp)<0) printf_log(LOG_INFO, "%s failed\n", tmp);
+ // setup LD_LIBRARY_PATH
+ const char* ld = getenv("LD_LIBRARY_PATH");
+ snprintf(tmp, sizeof(tmp), "%s/lib/x86_64-linux-gnu:%s/lib/i386-linux-gnu:%s/lib:%s/lib64:%s", sniper, sniper, sniper, ld?ld:"");
+ setenv("LD_LIBRARY_PATH", tmp, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", "LD_LIBRARY_PATH", tmp);
+ }
+ // do XDG_DATA_DIRS
+ {
+ char tmp[MAX_PATH*4] = {0};
+ const char* xdg = getenv("XDG_DATA_DIRS");
+ snprintf(tmp, sizeof(tmp), "%s/share:%s", sniper, xdg?xdg:"");
+ setenv("XDG_DATA_DIRS", tmp, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", "XDG_DATA_DIRS", tmp);
+ }
+ // disabled GI_TYPELIB_PATH for now
+ if(0)
+ {
+ char tmp[MAX_PATH*4] = {0};
+ snprintf(tmp, sizeof(tmp), "%s/lib/x86_64-linux-gnu/girepository-1.0:%s/lib/i386-linux-gnu/girepository-1.0:%s/lib/girepository-1.0", sniper, sniper, sniper);
+ setenv("GI_TYPELIB_PATH", tmp, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", "GI_TYPELIB_PATH", tmp);
+ }
+ // disabled GST_PLUGIN_SYSTEM_PATH
+ if(0)
+ {
+ char tmp[MAX_PATH*4] = {0};
+ snprintf(tmp, sizeof(tmp), "%s/lib/x86_64-linux-gnu/gstreamer-1.0:%s/lib/i386-linux-gnu/gstreamer-1.0:%s/lib/gstreamer-1.0", sniper, sniper, sniper);
+ setenv("GST_PLUGIN_SYSTEM_PATH", tmp, 1);
+ printf_log(LOG_DEBUG, "setenv(%s, %s, 1)\n", "GST_PLUGIN_SYSTEM_PATH", tmp);
+ }
+ // should disable native gtk on box86 for now, until better wrapping of gstreamer is done on box86 too
+ // setenv("BOX86_NOGTK", "1", 1);
+ }
printf_log(LOG_DEBUG, "Ready to launch \"%s\", nextarg=%d, argc=%d\n", argv[nextarg], nextarg, argc);
- const char* prog = argv[nextarg];
+ prog = argv[nextarg];
my_context = NewBox64Context(argc - nextarg);
int x86 = my_context->box86path?FileIsX86ELF(argv[nextarg]):0;
int x64 = my_context->box64path?FileIsX64ELF(argv[nextarg]):0;
@@ -92,7 +169,8 @@ void pressure_vessel(int argc, const char** argv, int nextarg)
// parent process, wait the end of child
FreeBox64Context(&my_context);
int wstatus;
- waitpid(v, &wstatus, 0);
+ wait(&wstatus);
+ //waitpid(v, &wstatus, 0);
exit(0);
}
} \ No newline at end of file
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index 220e06a..9502505 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -6,7 +6,6 @@
#include <pthread.h>
#include <sys/mman.h>
#include <errno.h>
-#include <execinfo.h>
#include <wrappedlibs.h>
#include "custommem.h"
@@ -54,14 +53,14 @@ brick_t* NewBrick(void* old)
brick_t* ret = (brick_t*)box_calloc(1, sizeof(brick_t));
if(old)
old = old + NBRICK * sizeof(onebridge_t);
- void* ptr = my_mmap(thread_get_emu(), old, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT
+ void* ptr = my_mmap(NULL, old, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT
if(ptr == MAP_FAILED)
- ptr = my_mmap(thread_get_emu(), NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0);
+ ptr = my_mmap(NULL, NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0);
if(ptr == MAP_FAILED) {
printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t));
}
#ifdef DYNAREC
- setProtection((uintptr_t)ptr, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC | PROT_NOPROT | PROT_MMAP);
+ setProtection((uintptr_t)ptr, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC | PROT_NOPROT);
#endif
dynarec_log(LOG_INFO, "New Bridge brick at %p (size 0x%zx)\n", ptr, NBRICK*sizeof(onebridge_t));
ret->b = ptr;
@@ -82,11 +81,10 @@ void FreeBridge(bridge_t** bridge)
if(!bridge || !*bridge)
return;
brick_t *b = (*bridge)->head;
- x64emu_t* emu = thread_get_emu();
while(b) {
brick_t *n = b->next;
dynarec_log(LOG_INFO, "FreeBridge brick at %p (size 0x%zx)\n", b->b, NBRICK*sizeof(onebridge_t));
- my_munmap(emu, b->b, NBRICK*sizeof(onebridge_t));
+ my_munmap(NULL, b->b, NBRICK*sizeof(onebridge_t));
box_free(b);
b = n;
}
@@ -99,6 +97,7 @@ void FreeBridge(bridge_t** bridge)
void addBridgeName(void* addr, const char* name);
#endif
+//static const char* default_bridge = "bridge???";
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
{
brick_t *b = NULL;
@@ -125,10 +124,7 @@ uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char*
b->b[sz].f = (uintptr_t)fnc;
b->b[sz].C3 = N?0xC2:0xC3;
b->b[sz].N = N;
- #ifdef HAVE_TRACE
- if(name)
- addBridgeName(fnc, name);
- #endif
+ b->b[sz].name = name/*?name:default_bridge*/;
return (uintptr_t)&b->b[sz].CC;
}
@@ -238,34 +234,13 @@ uintptr_t AddVSyscall(bridge_t* bridge, int num)
return (uintptr_t)&b->b[sz].CC;
}
-#ifdef HAVE_TRACE
-KHASH_MAP_INIT_INT64(bridgename, const char*)
-static kh_bridgename_t *bridgename;
-void initBridgeName()
-{
- bridgename = kh_init(bridgename);
-}
-void finiBridgeName()
-{
- kh_destroy(bridgename, bridgename);
- bridgename = NULL;
-}
-void addBridgeName(void* addr, const char* name)
-{
- int ret;
- khint_t k = kh_put(bridgename, bridgename, (uintptr_t)addr, &ret);
- if(!ret) // already there
- return;
- kh_value(bridgename, k) = name;
-}
const char* getBridgeName(void* addr)
{
- khint_t k = kh_get(bridgename, bridgename, (uintptr_t)addr);
- if(k!=kh_end(bridgename))
- return kh_value(bridgename, k);
+ onebridge_t* one = (onebridge_t*)(((uintptr_t)addr/sizeof(onebridge_t))*sizeof(onebridge_t)); // align to start of bridge
+ if(one->C3==0xC3 && one->S=='S' && one->C=='C')
+ return one->name;
return NULL;
}
-#endif
// Alternate address handling
@@ -309,15 +284,9 @@ void cleanAlternate() {
void init_bridge_helper()
{
- #ifdef HAVE_TRACE
- initBridgeName();
- #endif
}
void fini_bridge_helper()
{
cleanAlternate();
- #ifdef HAVE_TRACE
- finiBridgeName();
- #endif
}
diff --git a/src/tools/bridge_private.h b/src/tools/bridge_private.h
index 0983cea..f59f587 100644
--- a/src/tools/bridge_private.h
+++ b/src/tools/bridge_private.h
@@ -14,12 +14,14 @@ typedef union onebridge_s {
uintptr_t f; // the function for the wrapper
uint8_t C3; // C2 or C3 ret
uint16_t N; // N in case of C2 ret
+ const char* name; // name of the function bridged
};
struct {
- uint8_t B8; // B8 00 11 22 33 mov rax, num
+ uint8_t B8; // B8 00 11 22 33 mov eax, num
uint32_t num;
uint8_t _0F; uint8_t _05; // 0F 05 syscall
uint8_t _C3; // C3 ret
+ const char* syscall_name; //not used for now
};
uint64_t dummy[4];
} onebridge_t;
diff --git a/src/tools/callback.c b/src/tools/callback.c
index 162c801..341a554 100644
--- a/src/tools/callback.c
+++ b/src/tools/callback.c
@@ -164,6 +164,13 @@ uint64_t RunSafeFunction(uintptr_t fnc, int nargs, ...)
Push64(emu, R_R10);
Push64(emu, R_R11);
Push64(emu, R_RAX);
+ deferred_flags_t old_df = emu->df;
+ multiuint_t old_op1 = emu->op1;
+ multiuint_t old_op2 = emu->op2;
+ multiuint_t old_res = emu->res;
+ multiuint_t old_op1_sav= emu->op1_sav;
+ multiuint_t old_res_sav= emu->res_sav;
+ deferred_flags_t old_df_sav= emu->df_sav;
R_RSP -= stackn*sizeof(void*); // need to push in reverse order
@@ -200,7 +207,14 @@ uint64_t RunSafeFunction(uintptr_t fnc, int nargs, ...)
R_RSP = old_rbp; // mov rsp, rbp
R_RBP = Pop64(emu); // pop rbp
-
+
+ emu->df = old_df;
+ emu->op1 = old_op1;
+ emu->op2 = old_op2;
+ emu->res = old_res;
+ emu->op1_sav = old_op1_sav;
+ emu->res_sav = old_res_sav;
+ emu->df_sav = old_df_sav;
return ret;
}
diff --git a/src/tools/gtkclass.c b/src/tools/gtkclass.c
index 269d842..569f346 100644
--- a/src/tools/gtkclass.c
+++ b/src/tools/gtkclass.c
@@ -21,9 +21,12 @@ int is_gtk3 = 0;
static bridge_t* my_bridge = NULL;
static const char* (*g_type_name)(size_t) = NULL;
+static size_t (*g_type_parent)(size_t) = NULL;
static void* (*g_type_class_peek)(size_t) = NULL;
#define GTKCLASS(A) static size_t my_##A = (size_t)-1;
+#define GTKIFACE(A) GTKCLASS(A)
GTKCLASSES()
+#undef GTKIFACE
#undef GTKCLASS
KHASH_SET_INIT_INT(signalmap)
@@ -42,21 +45,11 @@ typedef struct sigoffset_array_s {
KHASH_MAP_INIT_INT64(sigoffset, sigoffset_array_t)
static kh_sigoffset_t *my_sigoffset = NULL;
+KHASH_MAP_INIT_INT64(customclass, char*)
+static kh_customclass_t *my_customclass = NULL;
+
// ---- Defining the multiple functions now -----
-#define SUPER() \
-GO(0) \
-GO(1) \
-GO(2) \
-GO(3) \
-GO(4) \
-GO(5) \
-GO(6) \
-GO(7) \
-GO(8) \
-GO(9) \
-GO(10) \
-GO(11) \
-GO(12)
+#include "super80.h"
#define WRAPPED(A, NAME, RET, DEF, FMT, ...) \
static uintptr_t my_##NAME##_fct_##A = 0; \
@@ -80,6 +73,38 @@ static void* find_##NAME##_##A(void* fct) \
if(my_##NAME##_##A##_fct_5 == (uintptr_t)fct) return my_##NAME##_##A##_5; \
if(my_##NAME##_##A##_fct_6 == (uintptr_t)fct) return my_##NAME##_##A##_6; \
if(my_##NAME##_##A##_fct_7 == (uintptr_t)fct) return my_##NAME##_##A##_7; \
+ if(my_##NAME##_##A##_fct_8 == (uintptr_t)fct) return my_##NAME##_##A##_8; \
+ if(my_##NAME##_##A##_fct_9 == (uintptr_t)fct) return my_##NAME##_##A##_9; \
+ if(my_##NAME##_##A##_fct_10 == (uintptr_t)fct) return my_##NAME##_##A##_10; \
+ if(my_##NAME##_##A##_fct_11 == (uintptr_t)fct) return my_##NAME##_##A##_11; \
+ if(my_##NAME##_##A##_fct_12 == (uintptr_t)fct) return my_##NAME##_##A##_12; \
+ if(my_##NAME##_##A##_fct_13 == (uintptr_t)fct) return my_##NAME##_##A##_13; \
+ if(my_##NAME##_##A##_fct_14 == (uintptr_t)fct) return my_##NAME##_##A##_14; \
+ if(my_##NAME##_##A##_fct_15 == (uintptr_t)fct) return my_##NAME##_##A##_15; \
+ if(my_##NAME##_##A##_fct_16 == (uintptr_t)fct) return my_##NAME##_##A##_16; \
+ if(my_##NAME##_##A##_fct_17 == (uintptr_t)fct) return my_##NAME##_##A##_17; \
+ if(my_##NAME##_##A##_fct_18 == (uintptr_t)fct) return my_##NAME##_##A##_18; \
+ if(my_##NAME##_##A##_fct_19 == (uintptr_t)fct) return my_##NAME##_##A##_19; \
+ if(my_##NAME##_##A##_fct_20 == (uintptr_t)fct) return my_##NAME##_##A##_20; \
+ if(my_##NAME##_##A##_fct_21 == (uintptr_t)fct) return my_##NAME##_##A##_21; \
+ if(my_##NAME##_##A##_fct_22 == (uintptr_t)fct) return my_##NAME##_##A##_22; \
+ if(my_##NAME##_##A##_fct_23 == (uintptr_t)fct) return my_##NAME##_##A##_23; \
+ if(my_##NAME##_##A##_fct_24 == (uintptr_t)fct) return my_##NAME##_##A##_24; \
+ if(my_##NAME##_##A##_fct_25 == (uintptr_t)fct) return my_##NAME##_##A##_25; \
+ if(my_##NAME##_##A##_fct_26 == (uintptr_t)fct) return my_##NAME##_##A##_26; \
+ if(my_##NAME##_##A##_fct_27 == (uintptr_t)fct) return my_##NAME##_##A##_27; \
+ if(my_##NAME##_##A##_fct_28 == (uintptr_t)fct) return my_##NAME##_##A##_28; \
+ if(my_##NAME##_##A##_fct_29 == (uintptr_t)fct) return my_##NAME##_##A##_29; \
+ if(my_##NAME##_##A##_fct_30 == (uintptr_t)fct) return my_##NAME##_##A##_30; \
+ if(my_##NAME##_##A##_fct_31 == (uintptr_t)fct) return my_##NAME##_##A##_31; \
+ if(my_##NAME##_##A##_fct_32 == (uintptr_t)fct) return my_##NAME##_##A##_32; \
+ if(my_##NAME##_##A##_fct_33 == (uintptr_t)fct) return my_##NAME##_##A##_33; \
+ if(my_##NAME##_##A##_fct_34 == (uintptr_t)fct) return my_##NAME##_##A##_34; \
+ if(my_##NAME##_##A##_fct_35 == (uintptr_t)fct) return my_##NAME##_##A##_35; \
+ if(my_##NAME##_##A##_fct_36 == (uintptr_t)fct) return my_##NAME##_##A##_36; \
+ if(my_##NAME##_##A##_fct_37 == (uintptr_t)fct) return my_##NAME##_##A##_37; \
+ if(my_##NAME##_##A##_fct_38 == (uintptr_t)fct) return my_##NAME##_##A##_38; \
+ if(my_##NAME##_##A##_fct_39 == (uintptr_t)fct) return my_##NAME##_##A##_39; \
if(my_##NAME##_##A##_fct_0 == 0) {my_##NAME##_##A##_fct_0 = (uintptr_t)fct; return my_##NAME##_##A##_0; } \
if(my_##NAME##_##A##_fct_1 == 0) {my_##NAME##_##A##_fct_1 = (uintptr_t)fct; return my_##NAME##_##A##_1; } \
if(my_##NAME##_##A##_fct_2 == 0) {my_##NAME##_##A##_fct_2 = (uintptr_t)fct; return my_##NAME##_##A##_2; } \
@@ -88,7 +113,39 @@ static void* find_##NAME##_##A(void* fct) \
if(my_##NAME##_##A##_fct_5 == 0) {my_##NAME##_##A##_fct_5 = (uintptr_t)fct; return my_##NAME##_##A##_5; } \
if(my_##NAME##_##A##_fct_6 == 0) {my_##NAME##_##A##_fct_6 = (uintptr_t)fct; return my_##NAME##_##A##_6; } \
if(my_##NAME##_##A##_fct_7 == 0) {my_##NAME##_##A##_fct_7 = (uintptr_t)fct; return my_##NAME##_##A##_7; } \
- printf_log(LOG_NONE, "Warning, no more slot for " #NAME " gtkclass callback\n"); \
+ if(my_##NAME##_##A##_fct_8 == 0) {my_##NAME##_##A##_fct_8 = (uintptr_t)fct; return my_##NAME##_##A##_8; } \
+ if(my_##NAME##_##A##_fct_9 == 0) {my_##NAME##_##A##_fct_9 = (uintptr_t)fct; return my_##NAME##_##A##_9; } \
+ if(my_##NAME##_##A##_fct_10 == 0) {my_##NAME##_##A##_fct_10 = (uintptr_t)fct; return my_##NAME##_##A##_10; } \
+ if(my_##NAME##_##A##_fct_11 == 0) {my_##NAME##_##A##_fct_11 = (uintptr_t)fct; return my_##NAME##_##A##_11; } \
+ if(my_##NAME##_##A##_fct_12 == 0) {my_##NAME##_##A##_fct_12 = (uintptr_t)fct; return my_##NAME##_##A##_12; } \
+ if(my_##NAME##_##A##_fct_13 == 0) {my_##NAME##_##A##_fct_13 = (uintptr_t)fct; return my_##NAME##_##A##_13; } \
+ if(my_##NAME##_##A##_fct_14 == 0) {my_##NAME##_##A##_fct_14 = (uintptr_t)fct; return my_##NAME##_##A##_14; } \
+ if(my_##NAME##_##A##_fct_15 == 0) {my_##NAME##_##A##_fct_15 = (uintptr_t)fct; return my_##NAME##_##A##_15; } \
+ if(my_##NAME##_##A##_fct_16 == 0) {my_##NAME##_##A##_fct_16 = (uintptr_t)fct; return my_##NAME##_##A##_16; } \
+ if(my_##NAME##_##A##_fct_17 == 0) {my_##NAME##_##A##_fct_17 = (uintptr_t)fct; return my_##NAME##_##A##_17; } \
+ if(my_##NAME##_##A##_fct_18 == 0) {my_##NAME##_##A##_fct_18 = (uintptr_t)fct; return my_##NAME##_##A##_18; } \
+ if(my_##NAME##_##A##_fct_19 == 0) {my_##NAME##_##A##_fct_19 = (uintptr_t)fct; return my_##NAME##_##A##_19; } \
+ if(my_##NAME##_##A##_fct_20 == 0) {my_##NAME##_##A##_fct_20 = (uintptr_t)fct; return my_##NAME##_##A##_20; } \
+ if(my_##NAME##_##A##_fct_21 == 0) {my_##NAME##_##A##_fct_21 = (uintptr_t)fct; return my_##NAME##_##A##_21; } \
+ if(my_##NAME##_##A##_fct_22 == 0) {my_##NAME##_##A##_fct_22 = (uintptr_t)fct; return my_##NAME##_##A##_22; } \
+ if(my_##NAME##_##A##_fct_23 == 0) {my_##NAME##_##A##_fct_23 = (uintptr_t)fct; return my_##NAME##_##A##_23; } \
+ if(my_##NAME##_##A##_fct_24 == 0) {my_##NAME##_##A##_fct_24 = (uintptr_t)fct; return my_##NAME##_##A##_24; } \
+ if(my_##NAME##_##A##_fct_25 == 0) {my_##NAME##_##A##_fct_25 = (uintptr_t)fct; return my_##NAME##_##A##_25; } \
+ if(my_##NAME##_##A##_fct_26 == 0) {my_##NAME##_##A##_fct_26 = (uintptr_t)fct; return my_##NAME##_##A##_26; } \
+ if(my_##NAME##_##A##_fct_27 == 0) {my_##NAME##_##A##_fct_27 = (uintptr_t)fct; return my_##NAME##_##A##_27; } \
+ if(my_##NAME##_##A##_fct_28 == 0) {my_##NAME##_##A##_fct_28 = (uintptr_t)fct; return my_##NAME##_##A##_28; } \
+ if(my_##NAME##_##A##_fct_29 == 0) {my_##NAME##_##A##_fct_29 = (uintptr_t)fct; return my_##NAME##_##A##_29; } \
+ if(my_##NAME##_##A##_fct_30 == 0) {my_##NAME##_##A##_fct_30 = (uintptr_t)fct; return my_##NAME##_##A##_30; } \
+ if(my_##NAME##_##A##_fct_31 == 0) {my_##NAME##_##A##_fct_31 = (uintptr_t)fct; return my_##NAME##_##A##_31; } \
+ if(my_##NAME##_##A##_fct_32 == 0) {my_##NAME##_##A##_fct_32 = (uintptr_t)fct; return my_##NAME##_##A##_32; } \
+ if(my_##NAME##_##A##_fct_33 == 0) {my_##NAME##_##A##_fct_33 = (uintptr_t)fct; return my_##NAME##_##A##_33; } \
+ if(my_##NAME##_##A##_fct_34 == 0) {my_##NAME##_##A##_fct_34 = (uintptr_t)fct; return my_##NAME##_##A##_34; } \
+ if(my_##NAME##_##A##_fct_35 == 0) {my_##NAME##_##A##_fct_35 = (uintptr_t)fct; return my_##NAME##_##A##_35; } \
+ if(my_##NAME##_##A##_fct_36 == 0) {my_##NAME##_##A##_fct_36 = (uintptr_t)fct; return my_##NAME##_##A##_36; } \
+ if(my_##NAME##_##A##_fct_37 == 0) {my_##NAME##_##A##_fct_37 = (uintptr_t)fct; return my_##NAME##_##A##_37; } \
+ if(my_##NAME##_##A##_fct_38 == 0) {my_##NAME##_##A##_fct_38 = (uintptr_t)fct; return my_##NAME##_##A##_38; } \
+ if(my_##NAME##_##A##_fct_39 == 0) {my_##NAME##_##A##_fct_39 = (uintptr_t)fct; return my_##NAME##_##A##_39; } \
+ printf_log(LOG_NONE, "Warning, no more slot for " #A " " #NAME " gtkclass callback\n"); \
return NULL; \
}
@@ -104,6 +161,38 @@ static void* reverse_##NAME##_##A(wrapper_t W, void* fct)
if((void*)my_##NAME##_##A##_5 == fct) return (void*)my_##NAME##_##A##_fct_5;\
if((void*)my_##NAME##_##A##_6 == fct) return (void*)my_##NAME##_##A##_fct_6;\
if((void*)my_##NAME##_##A##_7 == fct) return (void*)my_##NAME##_##A##_fct_7;\
+ if((void*)my_##NAME##_##A##_8 == fct) return (void*)my_##NAME##_##A##_fct_8;\
+ if((void*)my_##NAME##_##A##_9 == fct) return (void*)my_##NAME##_##A##_fct_9;\
+ if((void*)my_##NAME##_##A##_10 == fct) return (void*)my_##NAME##_##A##_fct_10;\
+ if((void*)my_##NAME##_##A##_11 == fct) return (void*)my_##NAME##_##A##_fct_11;\
+ if((void*)my_##NAME##_##A##_12 == fct) return (void*)my_##NAME##_##A##_fct_12;\
+ if((void*)my_##NAME##_##A##_13 == fct) return (void*)my_##NAME##_##A##_fct_13;\
+ if((void*)my_##NAME##_##A##_14 == fct) return (void*)my_##NAME##_##A##_fct_14;\
+ if((void*)my_##NAME##_##A##_15 == fct) return (void*)my_##NAME##_##A##_fct_15;\
+ if((void*)my_##NAME##_##A##_16 == fct) return (void*)my_##NAME##_##A##_fct_16;\
+ if((void*)my_##NAME##_##A##_17 == fct) return (void*)my_##NAME##_##A##_fct_17;\
+ if((void*)my_##NAME##_##A##_18 == fct) return (void*)my_##NAME##_##A##_fct_18;\
+ if((void*)my_##NAME##_##A##_19 == fct) return (void*)my_##NAME##_##A##_fct_19;\
+ if((void*)my_##NAME##_##A##_20 == fct) return (void*)my_##NAME##_##A##_fct_20;\
+ if((void*)my_##NAME##_##A##_21 == fct) return (void*)my_##NAME##_##A##_fct_21;\
+ if((void*)my_##NAME##_##A##_22 == fct) return (void*)my_##NAME##_##A##_fct_22;\
+ if((void*)my_##NAME##_##A##_23 == fct) return (void*)my_##NAME##_##A##_fct_23;\
+ if((void*)my_##NAME##_##A##_24 == fct) return (void*)my_##NAME##_##A##_fct_24;\
+ if((void*)my_##NAME##_##A##_25 == fct) return (void*)my_##NAME##_##A##_fct_25;\
+ if((void*)my_##NAME##_##A##_26 == fct) return (void*)my_##NAME##_##A##_fct_26;\
+ if((void*)my_##NAME##_##A##_27 == fct) return (void*)my_##NAME##_##A##_fct_27;\
+ if((void*)my_##NAME##_##A##_28 == fct) return (void*)my_##NAME##_##A##_fct_28;\
+ if((void*)my_##NAME##_##A##_29 == fct) return (void*)my_##NAME##_##A##_fct_29;\
+ if((void*)my_##NAME##_##A##_30 == fct) return (void*)my_##NAME##_##A##_fct_30;\
+ if((void*)my_##NAME##_##A##_31 == fct) return (void*)my_##NAME##_##A##_fct_31;\
+ if((void*)my_##NAME##_##A##_32 == fct) return (void*)my_##NAME##_##A##_fct_32;\
+ if((void*)my_##NAME##_##A##_33 == fct) return (void*)my_##NAME##_##A##_fct_33;\
+ if((void*)my_##NAME##_##A##_34 == fct) return (void*)my_##NAME##_##A##_fct_34;\
+ if((void*)my_##NAME##_##A##_35 == fct) return (void*)my_##NAME##_##A##_fct_35;\
+ if((void*)my_##NAME##_##A##_36 == fct) return (void*)my_##NAME##_##A##_fct_36;\
+ if((void*)my_##NAME##_##A##_37 == fct) return (void*)my_##NAME##_##A##_fct_37;\
+ if((void*)my_##NAME##_##A##_38 == fct) return (void*)my_##NAME##_##A##_fct_38;\
+ if((void*)my_##NAME##_##A##_39 == fct) return (void*)my_##NAME##_##A##_fct_39;\
Dl_info info; \
if(dladdr(fct, &info)) \
return (void*)AddCheckBridge(my_bridge, W, fct, 0, NULL); \
@@ -121,14 +210,46 @@ static void autobridge_##NAME##_##A(wrapper_t W, void* fct) \
}
#define WRAPPER(A, NAME, RET, DEF, FMT, ...) \
-WRAPPED(0, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(1, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(2, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(3, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(4, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(5, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(6, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
-WRAPPED(7, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 0, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 1, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 2, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 3, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 4, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 5, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 6, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 7, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 8, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED( 9, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(10, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(11, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(12, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(13, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(14, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(15, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(16, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(17, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(18, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(19, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(20, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(21, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(22, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(23, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(24, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(25, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(26, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(27, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(28, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(29, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(30, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(31, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(32, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(33, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(34, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(35, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(36, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(37, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(38, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
+WRAPPED(39, NAME##_##A, RET, DEF, FMT, __VA_ARGS__) \
FIND(A, NAME) \
REVERSE(A, NAME) \
AUTOBRIDGE(A, NAME)
@@ -177,6 +298,15 @@ static void bridgeGObjectClass(my_GObjectClass_t* class)
}
#undef SUPERGO
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGObjectInstance(my_GObject_t* class)
+{
+}
+// autobridge
+static void bridgeGObjectInstance(my_GObject_t* class)
+{
+}
+#undef SUPERGO
// ----- GInitiallyUnownedClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GInitiallyUnowned, constructor, void*, (size_t type, uint32_t n_construct_properties, void* construct_properties), "Lup", type, n_construct_properties, construct_properties);
@@ -221,38 +351,13 @@ static void bridgeGInitiallyUnownedClass(my_GInitiallyUnownedClass_t* class)
}
#undef SUPERGO
-// ----- GamesScoresImporterClass ------
-// wrapper x86 -> natives of callbacks
-WRAPPER(GamesScoresImporter, importOldScores, void, (void *self, void* context, void* new_scores_dir, void *error), "pppp", self, context, new_scores_dir, error);
-
-#define SUPERGO() \
- GO(importOldScores, vFpppp);
-
-// wrap (so bridge all calls, just in case)
-static void wrapGamesScoresImporterClass(my_GamesScoresImporterClass_t* class)
+static void unwrapGInitiallyUnownedInstance(my_GInitiallyUnowned_t* class)
{
- wrapGObjectClass(&class->parent_class);
- #define GO(A, W) class->A = reverse_##A##_GamesScoresImporter (W, class->A)
- SUPERGO()
- #undef GO
-}
-// unwrap (and use callback if not a native call anymore)
-static void unwrapGamesScoresImporterClass(my_GamesScoresImporterClass_t* class)
-{
- unwrapGObjectClass(&class->parent_class);
- #define GO(A, W) class->A = find_##A##_GamesScoresImporter (class->A)
- SUPERGO()
- #undef GO
}
// autobridge
-static void bridgeGamesScoresImporterClass(my_GamesScoresImporterClass_t* class)
+static void bridgeGInitiallyUnownedInstance(my_GInitiallyUnowned_t* class)
{
- bridgeGObjectClass(&class->parent_class);
- #define GO(A, W) autobridge_##A##_GamesScoresImporter (W, class->A)
- SUPERGO()
- #undef GO
}
-#undef SUPERGO
// ----- GApplicationClass ------
// wrapper x86 -> natives of callbacks
@@ -292,6 +397,7 @@ WRAPPER(GApplication, name_lost, void, (void* application), "p", application);
// wrap (so bridge all calls, just in case)
static void wrapGApplicationClass(my_GApplicationClass_t* class)
{
+ wrapGObjectClass(&class->parent_class);
#define GO(A, W) class->A = reverse_##A##_GApplication (W, class->A)
SUPERGO()
#undef GO
@@ -299,6 +405,7 @@ static void wrapGApplicationClass(my_GApplicationClass_t* class)
// unwrap (and use callback if not a native call anymore)
static void unwrapGApplicationClass(my_GApplicationClass_t* class)
{
+ unwrapGObjectClass(&class->parent_class);
#define GO(A, W) class->A = find_##A##_GApplication (class->A) //SUPERGO() defined but not used
SUPERGO()
#undef GO
@@ -306,6 +413,7 @@ static void unwrapGApplicationClass(my_GApplicationClass_t* class)
// autobridge
static void bridgeGApplicationClass(my_GApplicationClass_t* class)
{
+ bridgeGObjectClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GApplication (W, class->A)
SUPERGO()
#undef GO
@@ -313,6 +421,17 @@ static void bridgeGApplicationClass(my_GApplicationClass_t* class)
#undef SUPERGO
+static void unwrapGApplicationInstance(my_GApplication_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGApplicationInstance(my_GApplication_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+#undef SUPERGO
+
// ----- GtkApplicationClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkApplication, window_added, void, (void* application, void* window), "pp", application, window);
@@ -348,6 +467,16 @@ static void bridgeGtkApplicationClass(my_GtkApplicationClass_t* class)
#undef SUPERGO
+static void unwrapGtkApplicationInstance(my_GtkApplication_t* class)
+{
+ unwrapGApplicationInstance(&class->parent);
+}
+
+static void bridgeGtkApplicationInstance(my_GtkApplication_t* class)
+{
+ bridgeGApplicationInstance(&class->parent);
+}
+
// ----- GtkObjectClass ------
// wrapper x64 -> natives of callbacks
WRAPPER(GtkObject, set_arg, void, (void* object, void* arg, uint32_t arg_id), "ppu", object, arg, arg_id);
@@ -361,7 +490,7 @@ WRAPPER(GtkObject, destroy, void, (void* object), "p", object);
// wrap (so bridge all calls, just in case)
static void wrapGtkObjectClass(my_GtkObjectClass_t* class)
{
- wrapGObjectClass(&class->parent_class);
+ wrapGInitiallyUnownedClass(&class->parent_class);
#define GO(A, W) class->A = reverse_##A##_GtkObject (W, class->A)
SUPERGO()
#undef GO
@@ -369,7 +498,7 @@ static void wrapGtkObjectClass(my_GtkObjectClass_t* class)
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkObjectClass(my_GtkObjectClass_t* class)
{
- unwrapGObjectClass(&class->parent_class);
+ unwrapGInitiallyUnownedClass(&class->parent_class);
#define GO(A, W) class->A = find_##A##_GtkObject (class->A)
SUPERGO()
#undef GO
@@ -377,7 +506,7 @@ static void unwrapGtkObjectClass(my_GtkObjectClass_t* class)
// autobridge
static void bridgeGtkObjectClass(my_GtkObjectClass_t* class)
{
- bridgeGObjectClass(&class->parent_class);
+ bridgeGInitiallyUnownedClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkObject (W, class->A)
SUPERGO()
#undef GO
@@ -385,6 +514,16 @@ static void bridgeGtkObjectClass(my_GtkObjectClass_t* class)
#undef SUPERGO
+static void unwrapGtkObjectInstance(my_GtkObject_t* class)
+{
+ unwrapGInitiallyUnownedInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkObjectInstance(my_GtkObject_t* class)
+{
+ bridgeGInitiallyUnownedInstance(&class->parent);
+}
+
// ----- GtkWidget2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkWidget2, dispatch_child_properties_changed, void, (void* widget, uint32_t n_pspecs, void* pspecs), "pup", widget, n_pspecs, pspecs);
@@ -549,6 +688,16 @@ static void bridgeGtkWidget2Class(my_GtkWidget2Class_t* class)
#undef SUPERGO
+static void unwrapGtkWidget2Instance(my_GtkWidget2_t* class)
+{
+ unwrapGtkObjectInstance(&class->private);
+}
+// autobridge
+static void bridgeGtkWidget2Instance(my_GtkWidget2_t* class)
+{
+ bridgeGtkObjectInstance(&class->private);
+}
+
// ----- GtkWidget3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkWidget3, dispatch_child_properties_changed, void, (void* widget, uint32_t n_pspecs, void* pspecs), "pup", widget, n_pspecs, pspecs);
@@ -746,6 +895,16 @@ static void bridgeGtkWidget3Class(my_GtkWidget3Class_t* class)
#undef SUPERGO
+static void unwrapGtkWidget3Instance(my_GtkWidget3_t* class)
+{
+ unwrapGInitiallyUnownedInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkWidget3Instance(my_GtkWidget3_t* class)
+{
+ bridgeGInitiallyUnownedInstance(&class->parent);
+}
+
// ----- GtkContainer2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkContainer2, add, void, (void* container, void* widget), "pp", container, widget);
@@ -796,6 +955,16 @@ static void bridgeGtkContainer2Class(my_GtkContainer2Class_t* class)
#undef SUPERGO
+static void unwrapGtkContainer2Instance(my_GtkContainer2_t* class)
+{
+ unwrapGtkWidget2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkContainer2Instance(my_GtkContainer2_t* class)
+{
+ bridgeGtkWidget2Instance(&class->parent);
+}
+
// ----- GtkContainer3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkContainer3, add, void, (void* container, void* widget), "pp", container, widget);
@@ -848,6 +1017,16 @@ static void bridgeGtkContainer3Class(my_GtkContainer3Class_t* class)
#undef SUPERGO
+static void unwrapGtkContainer3Instance(my_GtkContainer3_t* class)
+{
+ unwrapGtkWidget3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkContainer3Instance(my_GtkContainer3_t* class)
+{
+ bridgeGtkWidget3Instance(&class->parent);
+}
+
// ----- GtkActionClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkAction, activate, void, (void* action), "p", action);
@@ -891,6 +1070,16 @@ static void bridgeGtkActionClass(my_GtkActionClass_t* class)
}
#undef SUPERGO
+static void unwrapGtkActionInstance(my_GtkAction_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkActionInstance(my_GtkAction_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+
// ----- GtkMisc2Class ------
// wrap (so bridge all calls, just in case)
@@ -909,6 +1098,15 @@ static void bridgeGtkMisc2Class(my_GtkMisc2Class_t* class)
bridgeGtkWidget2Class(&class->parent_class);
}
+static void unwrapGtkMisc2Instance(my_GtkMisc2_t* class)
+{
+ unwrapGtkWidget2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkMisc2Instance(my_GtkMisc2_t* class)
+{
+ bridgeGtkWidget2Instance(&class->parent);
+}
// ----- GtkMisc3Class ------
// no wrapper x86 -> natives of callbacks
@@ -941,38 +1139,44 @@ static void bridgeGtkMisc3Class(my_GtkMisc3Class_t* class)
#undef SUPERGO
-// ----- GtkGtkMenuButtonClass ------
-// wrapper x86 -> natives of callbacks
-WRAPPER(GtkMenuButton, activate, void, (void* self), "p", self);
+static void unwrapGtkMisc3Instance(my_GtkMisc3_t* class)
+{
+ unwrapGtkWidget3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkMisc3Instance(my_GtkMisc3_t* class)
+{
+ bridgeGtkWidget3Instance(&class->parent);
+}
-#define SUPERGO() \
- GO(activate, vFp);
+// ----- GtkImage3Class ------
// wrap (so bridge all calls, just in case)
-static void wrapGtkMenuButtonClass(my_GtkMenuButtonClass_t* class)
+static void wrapGtkImage3Class(my_GtkImage3Class_t* class)
{
- wrapGtkWidget3Class(&class->parent_class);
- #define GO(A, W) class->A = reverse_##A##_GtkMenuButton (W, class->A)
- SUPERGO()
- #undef GO
+ wrapGtkMisc3Class(&class->parent_class);
}
// unwrap (and use callback if not a native call anymore)
-static void unwrapGtkMenuButtonClass(my_GtkMenuButtonClass_t* class)
+static void unwrapGtkImage3Class(my_GtkImage3Class_t* class)
{
- unwrapGtkWidget3Class(&class->parent_class);
- #define GO(A, W) class->A = find_##A##_GtkMenuButton (class->A)
- SUPERGO()
- #undef GO
+ unwrapGtkMisc3Class(&class->parent_class);
}
// autobridge
-static void bridgeGtkMenuButtonClass(my_GtkMenuButtonClass_t* class)
+static void bridgeGtkImage3Class(my_GtkImage3Class_t* class)
{
- bridgeGtkWidget3Class(&class->parent_class);
- #define GO(A, W) autobridge_##A##_GtkMenuButton (W, class->A)
- SUPERGO()
- #undef GO
+ bridgeGtkMisc3Class(&class->parent_class);
}
-#undef SUPERGO
+
+static void unwrapGtkImage3Instance(my_GtkImage3_t* class)
+{
+ unwrapGtkMisc3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkImage3Instance(my_GtkImage3_t* class)
+{
+ bridgeGtkMisc3Instance(&class->parent);
+}
+
// ----- GtkLabel2Class ------
// wrapper x86 -> natives of callbacks
@@ -1013,6 +1217,16 @@ static void bridgeGtkLabel2Class(my_GtkLabel2Class_t* class)
}
#undef SUPERGO
+static void unwrapGtkLabel2Instance(my_GtkLabel2_t* class)
+{
+ unwrapGtkMisc2Instance(&class->misc);
+}
+// autobridge
+static void bridgeGtkLabel2Instance(my_GtkLabel2_t* class)
+{
+ bridgeGtkMisc2Instance(&class->misc);
+}
+
// ----- GtkLabel3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkLabel3, move_cursor, void, (void* label, int step, int count, int extend_selection), "piii", label, step, count, extend_selection);
@@ -1053,6 +1267,16 @@ static void bridgeGtkLabel3Class(my_GtkLabel3Class_t* class)
#undef SUPERGO
+static void unwrapGtkLabel3Instance(my_GtkLabel3_t* class)
+{
+ unwrapGtkMisc3Instance(&class->misc);
+}
+// autobridge
+static void bridgeGtkLabel3Instance(my_GtkLabel3_t* class)
+{
+ bridgeGtkMisc3Instance(&class->misc);
+}
+
// ----- GtkTreeView2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkTreeView2, set_scroll_adjustments, void, (void* tree_view, void* hadjustment, void* vadjustment), "ppp", tree_view, hadjustment, vadjustment);
@@ -1117,6 +1341,16 @@ static void bridgeGtkTreeView2Class(my_GtkTreeView2Class_t* class)
#undef SUPERGO
+static void unwrapGtkTreeView2Instance(my_GtkTreeView2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkTreeView2Instance(my_GtkTreeView2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->parent);
+}
+
// ----- GtkBin2Class ------
// wrap (so bridge all calls, just in case)
@@ -1135,6 +1369,16 @@ static void bridgeGtkBin2Class(my_GtkBin2Class_t* class)
bridgeGtkContainer2Class(&class->parent_class);
}
+static void unwrapGtkBin2Instance(my_GtkBin2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->container);
+}
+// autobridge
+static void bridgeGtkBin2Instance(my_GtkBin2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->container);
+}
+
// ----- GtkBin3Class ------
static void wrapGtkBin3Class(my_GtkBin3Class_t* class)
{
@@ -1151,6 +1395,15 @@ static void bridgeGtkBin3Class(my_GtkBin3Class_t* class)
bridgeGtkContainer3Class(&class->parent_class);
}
+static void unwrapGtkBin3Instance(my_GtkBin3_t* class)
+{
+ unwrapGtkContainer3Instance(&class->container);
+}
+// autobridge
+static void bridgeGtkBin3Instance(my_GtkBin3_t* class)
+{
+ bridgeGtkContainer3Instance(&class->container);
+}
// ----- GtkWindow2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkWindow2, set_focus, void, (void* window, void* focus), "pp", window, focus);
@@ -1196,6 +1449,16 @@ static void bridgeGtkWindow2Class(my_GtkWindow2Class_t* class)
#undef SUPERGO
+static void unwrapGtkWindow2Instance(my_GtkWindow2_t* class)
+{
+ unwrapGtkBin2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkWindow2Instance(my_GtkWindow2_t* class)
+{
+ bridgeGtkBin2Instance(&class->parent);
+}
+
// ----- GtkWindow3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkWindow3, set_focus, void, (void* window, void* focus), "pp", window, focus);
@@ -1239,6 +1502,16 @@ static void bridgeGtkWindow3Class(my_GtkWindow3Class_t* class)
#undef SUPERGO
+static void unwrapGtkWindow3Instance(my_GtkWindow3_t* class)
+{
+ unwrapGtkBin3Instance(&class->bin);
+}
+// autobridge
+static void bridgeGtkWindow3Instance(my_GtkWindow3_t* class)
+{
+ bridgeGtkBin3Instance(&class->bin);
+}
+
// ----- GtkApplicationWindowClass ------
// wrap (so bridge all calls, just in case)
static void wrapGtkApplicationWindowClass(my_GtkApplicationWindowClass_t* class)
@@ -1256,6 +1529,15 @@ static void bridgeGtkApplicationWindowClass(my_GtkApplicationWindowClass_t* clas
bridgeGtkWindow3Class(&class->parent_class);
}
+static void unwrapGtkApplicationWindowInstance(my_GtkApplicationWindow_t* class)
+{
+ unwrapGtkWindow3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkApplicationWindowInstance(my_GtkApplicationWindow_t* class)
+{
+ bridgeGtkWindow3Instance(&class->parent);
+}
// ----- GtkListBoxClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkListBoxClass,row_selected, void, (void *box, void *row), "pp", box, row);
@@ -1304,6 +1586,16 @@ static void bridgeGtkListBoxClass(my_GtkListBoxClass_t* class)
#undef SUPERGO
+static void unwrapGtkListBoxInstance(my_GtkListBox_t* class)
+{
+ unwrapGtkContainer3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkListBoxInstance(my_GtkListBox_t* class)
+{
+ bridgeGtkContainer3Instance(&class->parent);
+}
+
// ----- GtkListBoxRowClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkListBoxRowClass, activate, void, (void *row), "p", row);
@@ -1338,6 +1630,16 @@ static void bridgeGtkListBoxRowClass(my_GtkListBoxRowClass_t* class)
#undef SUPERGO
+static void unwrapGtkListBoxRowInstance(my_GtkListBoxRow_t* class)
+{
+ unwrapGtkBin3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkListBoxRowInstance(my_GtkListBoxRow_t* class)
+{
+ bridgeGtkBin3Instance(&class->parent);
+}
+
// ----- GtkTable2Class ------
// wrap (so bridge all calls, just in case)
static void wrapGtkTable2Class(my_GtkTable2Class_t* class)
@@ -1355,6 +1657,15 @@ static void bridgeGtkTable2Class(my_GtkTable2Class_t* class)
bridgeGtkContainer2Class(&class->parent_class);
}
+static void unwrapGtkTable2Instance(my_GtkTable2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->container);
+}
+// autobridge
+static void bridgeGtkTable2Instance(my_GtkTable2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->container);
+}
// ----- GtkFixed2Class ------
// wrap (so bridge all calls, just in case)
@@ -1373,6 +1684,44 @@ static void bridgeGtkFixed2Class(my_GtkFixed2Class_t* class)
bridgeGtkContainer2Class(&class->parent_class);
}
+static void unwrapGtkFixed2Instance(my_GtkFixed2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkFixed2Instance(my_GtkFixed2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->parent);
+}
+
+// ----- GtkFixed3Class ------
+
+// wrap (so bridge all calls, just in case)
+static void wrapGtkFixed3Class(my_GtkFixed3Class_t* class)
+{
+ wrapGtkContainer3Class(&class->parent_class);
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGtkFixed3Class(my_GtkFixed3Class_t* class)
+{
+ unwrapGtkContainer3Class(&class->parent_class);
+}
+// autobridge
+static void bridgeGtkFixed3Class(my_GtkFixed3Class_t* class)
+{
+ bridgeGtkContainer3Class(&class->parent_class);
+}
+
+static void unwrapGtkFixed3Instance(my_GtkFixed3_t* class)
+{
+ unwrapGtkContainer3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkFixed3Instance(my_GtkFixed3_t* class)
+{
+ bridgeGtkContainer3Instance(&class->parent);
+}
+
// ----- MetaFrames2Class ------
// wrap (so bridge all calls, just in case)
@@ -1391,6 +1740,15 @@ static void bridgeMetaFrames2Class(my_MetaFrames2Class_t* class)
bridgeGtkWindow2Class(&class->parent_class);
}
+static void unwrapMetaFrames2Instance(my_MetaFrames2_t* class)
+{
+ unwrapGtkWindow2Instance(&class->parent);
+}
+// autobridge
+static void bridgeMetaFrames2Instance(my_MetaFrames2_t* class)
+{
+ bridgeGtkWindow2Instance(&class->parent);
+}
// ----- GDBusObjectManagerClientClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GDBusObjectManagerClient,interface_proxy_signal, void, (void* manager, void* object_proxy, void* interface_proxy, void* sender_name, void* signal_name, void* parameters), "pppppp", manager, object_proxy, interface_proxy, sender_name, signal_name, parameters);
@@ -1428,6 +1786,16 @@ static void bridgeGDBusObjectManagerClientClass(my_GDBusObjectManagerClientClass
#undef SUPERGO
+static void unwrapGDBusObjectManagerClientInstance(my_GDBusObjectManagerClient_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGDBusObjectManagerClientInstance(my_GDBusObjectManagerClient_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+
// ----- GtkButton2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkButton2, pressed, void, (void* button), "p", button);
@@ -1473,6 +1841,16 @@ static void bridgeGtkButton2Class(my_GtkButton2Class_t* class)
#undef SUPERGO
+static void unwrapGtkButton2Instance(my_GtkButton2_t* class)
+{
+ unwrapGtkBin2Instance(&class->bin);
+}
+// autobridge
+static void bridgeGtkButton2Instance(my_GtkButton2_t* class)
+{
+ bridgeGtkBin2Instance(&class->bin);
+}
+
// ----- GtkButton3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkButton3, pressed, void, (void* button), "p", button);
@@ -1518,6 +1896,16 @@ static void bridgeGtkButton3Class(my_GtkButton3Class_t* class)
#undef SUPERGO
+static void unwrapGtkButton3Instance(my_GtkButton3_t* class)
+{
+ unwrapGtkBin3Instance(&class->bin);
+}
+// autobridge
+static void bridgeGtkButton3Instance(my_GtkButton3_t* class)
+{
+ bridgeGtkBin3Instance(&class->bin);
+}
+
// ----- GtkComboBox2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkComboBox2, changed, void, (void* combo_box), "p", combo_box);
@@ -1555,6 +1943,16 @@ static void bridgeGtkComboBox2Class(my_GtkComboBox2Class_t* class)
#undef SUPERGO
+static void unwrapGtkComboBox2Instance(my_GtkComboBox2_t* class)
+{
+ unwrapGtkBin2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkComboBox2Instance(my_GtkComboBox2_t* class)
+{
+ bridgeGtkBin2Instance(&class->parent);
+}
+
// ----- GtkToggleButton2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkToggleButton2, toggled, void, (void* toggle_button), "p", toggle_button);
@@ -1590,6 +1988,61 @@ static void bridgeGtkToggleButton2Class(my_GtkToggleButton2Class_t* class)
#undef SUPERGO
+static void unwrapGtkToggleButton2Instance(my_GtkToggleButton2_t* class)
+{
+ unwrapGtkButton2Instance(&class->button);
+}
+// autobridge
+static void bridgeGtkToggleButton2Instance(my_GtkToggleButton2_t* class)
+{
+ bridgeGtkButton2Instance(&class->button);
+}
+
+// ----- GtkToggleButton3Class ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GtkToggleButton3, toggled, void, (void* toggle_button), "p", toggle_button);
+
+#define SUPERGO() \
+ GO(toggled, vFp); \
+
+
+// wrap (so bridge all calls, just in case)
+static void wrapGtkToggleButton3Class(my_GtkToggleButton3Class_t* class)
+{
+ wrapGtkButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GtkToggleButton3 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGtkToggleButton3Class(my_GtkToggleButton3Class_t* class)
+{
+ unwrapGtkButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GtkToggleButton3 (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGtkToggleButton3Class(my_GtkToggleButton3Class_t* class)
+{
+ bridgeGtkButton3Class(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GtkToggleButton2 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGtkToggleButton3Instance(my_GtkToggleButton3_t* class)
+{
+ unwrapGtkButton3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkToggleButton3Instance(my_GtkToggleButton3_t* class)
+{
+ bridgeGtkButton3Instance(&class->parent);
+}
+
// ----- GtkCheckButton2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkCheckButton2, draw_indicator, void, (void* check_button, void* area), "pp", check_button, area);
@@ -1625,6 +2078,100 @@ static void bridgeGtkCheckButton2Class(my_GtkCheckButton2Class_t* class)
#undef SUPERGO
+static void unwrapGtkCheckButton2Instance(my_GtkCheckButton2_t* class)
+{
+ unwrapGtkToggleButton2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkCheckButton2Instance(my_GtkCheckButton2_t* class)
+{
+ bridgeGtkToggleButton2Instance(&class->parent);
+}
+
+// ----- GtkCheckButton3Class ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GtkCheckButton3, draw_indicator, void, (void* check_button, void* area), "pp", check_button, area);
+
+#define SUPERGO() \
+ GO(draw_indicator, vFpp); \
+
+
+// wrap (so bridge all calls, just in case)
+static void wrapGtkCheckButton3Class(my_GtkCheckButton3Class_t* class)
+{
+ wrapGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GtkCheckButton3 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGtkCheckButton3Class(my_GtkCheckButton3Class_t* class)
+{
+ unwrapGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GtkCheckButton3 (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGtkCheckButton3Class(my_GtkCheckButton3Class_t* class)
+{
+ bridgeGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GtkCheckButton3 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGtkCheckButton3Instance(my_GtkCheckButton3_t* class)
+{
+ unwrapGtkToggleButton3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkCheckButton3Instance(my_GtkCheckButton3_t* class)
+{
+ bridgeGtkToggleButton3Instance(&class->parent);
+}
+// ----- GtkGtkMenuButton3Class ------
+// wrapper x86 -> natives of callbacks
+
+#define SUPERGO() \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGtkMenuButton3Class(my_GtkMenuButton3Class_t* class)
+{
+ wrapGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GtkMenuButton3 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGtkMenuButton3Class(my_GtkMenuButton3Class_t* class)
+{
+ unwrapGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GtkMenuButton3 (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGtkMenuButton3Class(my_GtkMenuButton3Class_t* class)
+{
+ bridgeGtkToggleButton3Class(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GtkMenuButton3 (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGtkMenuButton3Instance(my_GtkMenuButton3_t* class)
+{
+ unwrapGtkToggleButton3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkMenuButton3Instance(my_GtkMenuButton3_t* class)
+{
+ bridgeGtkToggleButton3Instance(&class->parent);
+}
// ----- GtkEntry2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkEntry2, populate_popup, void, (void* entry, void* menu), "pp", entry, menu);
@@ -1679,6 +2226,16 @@ static void bridgeGtkEntry2Class(my_GtkEntry2Class_t* class)
#undef SUPERGO
+static void unwrapGtkEntry2Instance(my_GtkEntry2_t* class)
+{
+ unwrapGtkWidget2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkEntry2Instance(my_GtkEntry2_t* class)
+{
+ bridgeGtkWidget2Instance(&class->parent);
+}
+
// ----- GtkSpinButton2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkSpinButton2, input, int, (void* spin_button, void* new_value), "pp", spin_button, new_value);
@@ -1721,6 +2278,16 @@ static void bridgeGtkSpinButton2Class(my_GtkSpinButton2Class_t* class)
#undef SUPERGO
+static void unwrapGtkSpinButton2Instance(my_GtkSpinButton2_t* class)
+{
+ unwrapGtkEntry2Instance(&class->entry);
+}
+// autobridge
+static void bridgeGtkSpinButton2Instance(my_GtkSpinButton2_t* class)
+{
+ bridgeGtkEntry2Instance(&class->entry);
+}
+
// ----- GtkProgress2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkProgress2, paint, void, (void* progress), "p", progress);
@@ -1735,7 +2302,7 @@ WRAPPER(GtkProgress2, act_mode_enter, void, (void* progress), "p", progress);
// wrap (so bridge all calls, just in case)
static void wrapGtkProgress2Class(my_GtkProgress2Class_t* class)
{
- wrapGtkWidget2Class(&class->parent_class);
+ wrapGtkWidget2Class(&class->parent);
#define GO(A, W) class->A = reverse_##A##_GtkProgress2 (W, class->A)
SUPERGO()
#undef GO
@@ -1743,7 +2310,7 @@ static void wrapGtkProgress2Class(my_GtkProgress2Class_t* class)
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkProgress2Class(my_GtkProgress2Class_t* class)
{
- unwrapGtkWidget2Class(&class->parent_class);
+ unwrapGtkWidget2Class(&class->parent);
#define GO(A, W) class->A = find_##A##_GtkProgress2 (class->A)
SUPERGO()
#undef GO
@@ -1751,7 +2318,7 @@ static void unwrapGtkProgress2Class(my_GtkProgress2Class_t* class)
// autobridge
static void bridgeGtkProgress2Class(my_GtkProgress2Class_t* class)
{
- bridgeGtkWidget2Class(&class->parent_class);
+ bridgeGtkWidget2Class(&class->parent);
#define GO(A, W) autobridge_##A##_GtkProgress2 (W, class->A)
SUPERGO()
#undef GO
@@ -1759,6 +2326,16 @@ static void bridgeGtkProgress2Class(my_GtkProgress2Class_t* class)
#undef SUPERGO
+static void unwrapGtkProgress2Instance(my_GtkProgress2_t* class)
+{
+ unwrapGtkWidget2Instance(&class->widget);
+}
+// autobridge
+static void bridgeGtkProgress2Instance(my_GtkProgress2_t* class)
+{
+ bridgeGtkWidget2Instance(&class->widget);
+}
+
// ----- GtkProgressBar2Class ------
// no wrapper x86 -> natives of callbacks
@@ -1791,6 +2368,16 @@ static void bridgeGtkProgressBar2Class(my_GtkProgressBar2Class_t* class)
#undef SUPERGO
+static void unwrapGtkProgressBar2Instance(my_GtkProgressBar2_t* class)
+{
+ unwrapGtkProgress2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkProgressBar2Instance(my_GtkProgressBar2_t* class)
+{
+ bridgeGtkProgress2Instance(&class->parent);
+}
+
// ----- GtkFrame2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkFrame2, compute_child_allocation, void, (void* frame, void* allocation), "pp", frame, allocation);
@@ -1825,6 +2412,16 @@ static void bridgeGtkFrame2Class(my_GtkFrame2Class_t* class)
#undef SUPERGO
+static void unwrapGtkFrame2Instance(my_GtkFrame2_t* class)
+{
+ unwrapGtkBin2Instance(&class->bin);
+}
+// autobridge
+static void bridgeGtkFrame2Instance(my_GtkFrame2_t* class)
+{
+ bridgeGtkBin2Instance(&class->bin);
+}
+
// ----- GtkMenuShell2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkMenuShell2,deactivate, void, (void* menu_shell), "p", menu_shell);
@@ -1875,6 +2472,16 @@ static void bridgeGtkMenuShell2Class(my_GtkMenuShell2Class_t* class)
#undef SUPERGO
+static void unwrapGtkMenuShell2Instance(my_GtkMenuShell2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->container);
+}
+// autobridge
+static void bridgeGtkMenuShell2Instance(my_GtkMenuShell2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->container);
+}
+
// ----- GtkMenuBar2Class ------
// no wrapper x86 -> natives of callbacks
@@ -1907,6 +2514,16 @@ static void bridgeGtkMenuBar2Class(my_GtkMenuBar2Class_t* class)
#undef SUPERGO
+static void unwrapGtkMenuBar2Instance(my_GtkMenuBar2_t* class)
+{
+ unwrapGtkMenuShell2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkMenuBar2Instance(my_GtkMenuBar2_t* class)
+{
+ bridgeGtkMenuShell2Instance(&class->parent);
+}
+
// ----- GtkTextView2Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkTextView2, set_scroll_adjustments, void, (void* text_view, void* hadjustment, void* vadjustment), "ppp", text_view, hadjustment, vadjustment);
@@ -1965,6 +2582,16 @@ static void bridgeGtkTextView2Class(my_GtkTextView2Class_t* class)
#undef SUPERGO
+static void unwrapGtkTextView2Instance(my_GtkTextView2_t* class)
+{
+ unwrapGtkContainer2Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkTextView2Instance(my_GtkTextView2_t* class)
+{
+ bridgeGtkContainer2Instance(&class->parent);
+}
+
// ----- GtkTextView3Class ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkTextView3, populate_popup, void, (void* text_view, void* menu), "pp", text_view, menu);
@@ -2025,6 +2652,16 @@ static void bridgeGtkTextView3Class(my_GtkTextView3Class_t* class)
#undef SUPERGO
+static void unwrapGtkTextView3Instance(my_GtkTextView3_t* class)
+{
+ unwrapGtkContainer3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkTextView3Instance(my_GtkTextView3_t* class)
+{
+ bridgeGtkContainer3Instance(&class->parent);
+}
+
// ----- GtkGrid3Class ------
// no wrapper x86 -> natives of callbacks
@@ -2057,6 +2694,16 @@ static void bridgeGtkGrid3Class(my_GtkGrid3Class_t* class)
#undef SUPERGO
+static void unwrapGtkGrid3Instance(my_GtkGrid3_t* class)
+{
+ unwrapGtkContainer3Instance(&class->parent);
+}
+// autobridge
+static void bridgeGtkGrid3Instance(my_GtkGrid3_t* class)
+{
+ bridgeGtkContainer3Instance(&class->parent);
+}
+
// ----- GtkEventControllerClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkEventController, set_widget, void, (void* controller, void* widget), "pp", controller, widget);
@@ -2101,6 +2748,16 @@ static void bridgeGtkEventControllerClass(my_GtkEventControllerClass_t* class)
#undef SUPERGO
+static void unwrapGtkEventControllerInstance(my_GtkEventController_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkEventControllerInstance(my_GtkEventController_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+
// ----- GtkGestureClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkGesture, check, void, (void* gesture), "p", gesture);
@@ -2145,6 +2802,16 @@ static void bridgeGtkGestureClass(my_GtkGestureClass_t* class)
#undef SUPERGO
+static void unwrapGtkGestureInstance(my_GtkGesture_t* class)
+{
+ unwrapGtkEventControllerInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkGestureInstance(my_GtkGesture_t* class)
+{
+ bridgeGtkEventControllerInstance(&class->parent);
+}
+
// ----- GtkGestureSingleClass ------
// wrap (so bridge all calls, just in case)
static void wrapGtkGestureSingleClass(my_GtkGestureSingleClass_t* class)
@@ -2162,6 +2829,15 @@ static void bridgeGtkGestureSingleClass(my_GtkGestureSingleClass_t* class)
bridgeGtkGestureClass(&class->parent_class);
}
+static void unwrapGtkGestureSingleInstance(my_GtkGestureSingle_t* class)
+{
+ unwrapGtkGestureInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkGestureSingleInstance(my_GtkGestureSingle_t* class)
+{
+ bridgeGtkGestureInstance(&class->parent);
+}
// ----- GtkGestureClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkGestureLongPress, pressed, void, (void *gesture, double x, double y), "pdd", gesture, x, y);
@@ -2198,6 +2874,16 @@ static void bridgeGtkGestureLongPressClass(my_GtkGestureLongPressClass_t* class)
#undef SUPERGO
+static void unwrapGtkGestureLongPressInstance(my_GtkGestureLongPress_t* class)
+{
+ unwrapGtkGestureSingleInstance(&class->parent);
+}
+// autobridge
+static void bridgeGtkGestureLongPressInstance(my_GtkGestureLongPress_t* class)
+{
+ bridgeGtkGestureSingleInstance(&class->parent);
+}
+
// ----- AtkObjectClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(AtkObject, get_name, void*, (void* accessible), "p", accessible);
@@ -2282,6 +2968,16 @@ static void bridgeAtkObjectClass(my_AtkObjectClass_t* class)
#undef SUPERGO
+static void unwrapAtkObjectInstance(my_AtkObject_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeAtkObjectInstance(my_AtkObject_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+
// ----- AtkUtilClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(AtkUtil,add_global_event_listener, uint32_t,(void* listener, void* event_type), "pp", AddCheckBridge(my_bridge, iFpupp, listener, 0, NULL), event_type);
@@ -2328,6 +3024,16 @@ static void bridgeAtkUtilClass(my_AtkUtilClass_t* class)
#undef SUPERGO
+static void unwrapAtkUtilInstance(my_AtkUtil_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeAtkUtilInstance(my_AtkUtil_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+
// ----- GstObjectClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GstObject, deep_notify, void, (void* object, void* origin, void* pspec), "ppp", object, origin, pspec);
@@ -2362,6 +3068,16 @@ static void bridgeGstObjectClass(my_GstObjectClass_t* class)
#undef SUPERGO
+static void unwrapGstObjectInstance(my_GstObject_t* class)
+{
+ unwrapGInitiallyUnownedInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstObjectInstance(my_GstObject_t* class)
+{
+ bridgeGInitiallyUnownedInstance(&class->parent);
+}
+
// ----- GstAllocatorClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GstAllocator, alloc, void*, (void *allocator, size_t size, void *params), "pLp", allocator, size, params);
@@ -2398,6 +3114,40 @@ static void bridgeGstAllocatorClass(my_GstAllocatorClass_t* class)
#undef SUPERGO
+WRAPPER(GstAllocatorInstance, mem_map, void*, (void* mem, size_t maxsize, int flags), "pLi", mem, maxsize, flags);
+WRAPPER(GstAllocatorInstance, mem_unmap, void , (void* mem), "p", mem);
+WRAPPER(GstAllocatorInstance, mem_copy, void*, (void* mem, ssize_t offset, ssize_t size), "pll", mem, offset, size);
+WRAPPER(GstAllocatorInstance, mem_share, void*, (void* mem, ssize_t offset, ssize_t size), "pll", mem, offset, size);
+WRAPPER(GstAllocatorInstance, mem_is_span, int , (void* mem1, void* mem2, void* offset), "ppp", mem1, mem2, offset);
+WRAPPER(GstAllocatorInstance, mem_map_full, void*, (void* mem, void* info, size_t maxsize), "ppL", mem, info, maxsize);
+WRAPPER(GstAllocatorInstance, mem_unmap_full, void ,(void* mem, void* info), "pp", mem, info);
+
+#define SUPERGO() \
+ GO(mem_map, pFpLi); \
+ GO(mem_unmap, vFp); \
+ GO(mem_copy, pFpll); \
+ GO(mem_share, pFpll); \
+ GO(mem_is_span, iFppp); \
+ GO(mem_map_full, pFppL); \
+ GO(mem_unmap_full, vFpp); \
+
+static void unwrapGstAllocatorInstance(my_GstAllocator_t* class)
+{
+ unwrapGstObjectInstance(&class->parent);
+ #define GO(A, W) class->A = find_##A##_GstAllocatorInstance (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstAllocatorInstance(my_GstAllocator_t* class)
+{
+ bridgeGstObjectInstance(&class->parent);
+ #define GO(A, W) autobridge_##A##_GstAllocatorInstance (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
// ----- GstTaskPoolClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GstTaskPool, prepare, void, (void* pool, void* error), "pp", pool, error);
@@ -2440,6 +3190,1234 @@ static void bridgeGstTaskPoolClass(my_GstTaskPoolClass_t* class)
#undef SUPERGO
+static void unwrapGstTaskPoolInstance(my_GstTaskPool_t* class)
+{
+ unwrapGstObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstTaskPoolInstance(my_GstTaskPool_t* class)
+{
+ bridgeGstObjectInstance(&class->parent);
+}
+
+// ----- GstElementClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstElement,pad_added, void, (void* element, void* pad), "pp", element, pad);
+WRAPPER(GstElement,pad_removed, void, (void* element, void* pad), "pp", element, pad);
+WRAPPER(GstElement,no_more_pads, void, (void* element), "p", element);
+WRAPPER(GstElement,request_new_pad, void*, (void* element, void* templ, void* name, void* caps), "pppp", element, templ, name, caps);
+WRAPPER(GstElement,release_pad, void, (void* element, void* pad), "pp", element, pad);
+WRAPPER(GstElement,get_state, int, (void* element, void* state, void* pending, uint64_t timeout), "pppU", element, state, pending, timeout);
+WRAPPER(GstElement,set_state, int, (void* element, int state), "pi", element, state);
+WRAPPER(GstElement,change_state, int, (void* element, int transition), "pi", element, transition);
+WRAPPER(GstElement,state_changed, void, (void* element, int oldstate, int newstate, int pending), "piii", element, oldstate, newstate, pending);
+WRAPPER(GstElement,set_bus, void, (void* element, void* bus), "pp", element, bus);
+WRAPPER(GstElement,provide_clock, void*, (void* element), "p", element);
+WRAPPER(GstElement,set_clock, int, (void* element, void* clock), "pp", element, clock);
+WRAPPER(GstElement,send_event, int, (void* element, void* event), "pp", element, event);
+WRAPPER(GstElement,query, int, (void* element, void* query), "pp", element, query);
+WRAPPER(GstElement,post_message, int, (void* element, void* message), "pp", element, message);
+WRAPPER(GstElement,set_context, void, (void* element, void* context), "pp", element, context);
+
+#define SUPERGO() \
+ GO(pad_added, vFpp); \
+ GO(pad_removed, vFpp); \
+ GO(no_more_pads, vFp); \
+ GO(request_new_pad, pFpppp);\
+ GO(release_pad, vFpp); \
+ GO(get_state, iFppU); \
+ GO(set_state, iFpi); \
+ GO(change_state, iFpi); \
+ GO(state_changed, vFpiii); \
+ GO(set_bus, vFpp); \
+ GO(provide_clock, pFp); \
+ GO(set_clock, iFpp); \
+ GO(send_event, iFpp); \
+ GO(query, iFpp); \
+ GO(post_message, iFpp); \
+ GO(set_context, vFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstElementClass(my_GstElementClass_t* class)
+{
+ wrapGstObjectClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstElement (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstElementClass(my_GstElementClass_t* class)
+{
+ unwrapGstObjectClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstElement (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstElementClass(my_GstElementClass_t* class)
+{
+ bridgeGstObjectClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstElement (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGstElementInstance(my_GstElement_t* class)
+{
+ unwrapGstObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstElementInstance(my_GstElement_t* class)
+{
+ bridgeGstObjectInstance(&class->parent);
+}
+#undef SUPERGO
+
+// ----- GstBinClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstBin,element_added, void, (void* bin, void* child), "pp", bin, child);
+WRAPPER(GstBin,element_removed, void, (void* bin, void* child), "pp", bin, child);
+WRAPPER(GstBin,add_element, int, (void* bin, void* element), "pp", bin, element);
+WRAPPER(GstBin,remove_element, int, (void* bin, void* element), "pp", bin, element);
+WRAPPER(GstBin,handle_message, void, (void* bin, void* message), "pp", bin, message);
+WRAPPER(GstBin,do_latency, int, (void* bin), "p", bin);
+WRAPPER(GstBin,deep_element_added, void, (void* bin, void* sub_bin, void* child), "ppp", bin, sub_bin, child);
+WRAPPER(GstBin,deep_element_removed, void, (void* bin, void* sub_bin, void* child), "ppp", bin, sub_bin, child);
+
+#define SUPERGO() \
+ GO(element_added, vFpp); \
+ GO(element_removed, vFpp); \
+ GO(add_element, iFpp); \
+ GO(remove_element, iFpp); \
+ GO(handle_message, vFpp); \
+ GO(do_latency, iFp); \
+ GO(deep_element_added, vFppp); \
+ GO(deep_element_removed, vFppp);\
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstBinClass(my_GstBinClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstBin (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstBinClass(my_GstBinClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstBin (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstBinClass(my_GstBinClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstBin (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGstBinInstance(my_GstBin_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstBinInstance(my_GstBin_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+
+// ----- GstBaseTransformClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstBaseTransform, transform_caps, void*, (void* trans, int direction, void* caps, void* filter), "pipp", trans, direction, caps, filter);
+WRAPPER(GstBaseTransform, fixate_caps, void*, (void* trans, int direction, void* caps, void* othercaps), "pipp", trans, direction, caps, othercaps);
+WRAPPER(GstBaseTransform, accept_caps, int, (void* trans, int direction, void* caps), "pip", trans, direction, caps);
+WRAPPER(GstBaseTransform, set_caps, int, (void* trans, void* incaps, void* outcaps), "ppp", trans, incaps, outcaps);
+WRAPPER(GstBaseTransform, query, int, (void* trans, int direction, void* query), "pip", trans, direction, query);
+WRAPPER(GstBaseTransform, decide_allocation, int, (void* trans, void* query), "pp", trans, query );
+WRAPPER(GstBaseTransform, filter_meta, int, (void* trans, void* query, size_t api, void* params), "ppLp", trans, query, api, params);
+WRAPPER(GstBaseTransform, propose_allocation, int, (void* trans, void* decide_query, void* query), "ppp", trans, decide_query, query );
+WRAPPER(GstBaseTransform, transform_size, int, (void* trans, int direction, void* caps, size_t size, void* othercaps, void* othersize), "pipLpp", trans, direction, caps, size, othercaps, othersize);
+WRAPPER(GstBaseTransform, get_unit_size, int, (void* trans, void* caps, void* size), "ppp", trans, caps, size);
+WRAPPER(GstBaseTransform, start, int, (void* trans), "p", trans);
+WRAPPER(GstBaseTransform, stop, int, (void* trans), "p", trans);
+WRAPPER(GstBaseTransform, sink_event, int, (void* trans, void* event), "pp", trans, event );
+WRAPPER(GstBaseTransform, src_event, int, (void* trans, void* event), "pp", trans, event );
+WRAPPER(GstBaseTransform, prepare_output_buffer, int, (void* trans, void* input, void* outbuf), "ppp", trans, input, outbuf );
+WRAPPER(GstBaseTransform, copy_metadata, int, (void* trans, void* input, void* outbuf), "ppp", trans, input, outbuf );
+WRAPPER(GstBaseTransform, transform_meta, int, (void* trans, void* outbuf, void* meta, void* inbuf), "pppp", trans, outbuf, meta, inbuf );
+WRAPPER(GstBaseTransform, before_transform, void, (void* trans, void* buffer), "pp", trans, buffer );
+WRAPPER(GstBaseTransform, transform, int, (void* trans, void* inbuf, void* outbuf), "ppp", trans, inbuf, outbuf );
+WRAPPER(GstBaseTransform, transform_ip, int, (void* trans, void* buf), "pp", trans, buf );
+WRAPPER(GstBaseTransform, submit_input_buffer, int, (void* trans, int is_discont, void* input), "pip", trans, is_discont, input );
+WRAPPER(GstBaseTransform, generate_output, int, (void* trans, void* outbuf), "pp", trans, outbuf );
+
+#define SUPERGO() \
+ GO(transform_caps, pFpipp); \
+ GO(fixate_caps, pFpipp); \
+ GO(accept_caps, iFpip); \
+ GO(set_caps, iFppp); \
+ GO(query, iFpip); \
+ GO(decide_allocation, iFpp); \
+ GO(filter_meta, iFppLp); \
+ GO(propose_allocation, iFppp); \
+ GO(transform_size, iFpipLpp); \
+ GO(get_unit_size, iFppp); \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(sink_event, iFpp); \
+ GO(src_event, iFpp); \
+ GO(prepare_output_buffer, iFppp); \
+ GO(copy_metadata, iFppp); \
+ GO(transform_meta, iFpppp); \
+ GO(before_transform, vFpp); \
+ GO(transform, iFppp); \
+ GO(transform_ip, iFpp); \
+ GO(submit_input_buffer, iFpip); \
+ GO(generate_output, iFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstBaseTransformClass(my_GstBaseTransformClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstBaseTransform (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstBaseTransformClass(my_GstBaseTransformClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstBaseTransform (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstBaseTransformClass(my_GstBaseTransformClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstBaseTransform (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGstBaseTransformInstance(my_GstBaseTransform_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstBaseTransformInstance(my_GstBaseTransform_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstVideoDecoderClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoDecoder, open, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, close, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, start, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, stop, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, parse, int, (void* decoder, void* frame, void* adapter, int at_eos), "pppi", decoder, frame, adapter, at_eos);
+WRAPPER(GstVideoDecoder, set_format, int, (void* decoder, void* state), "pp", decoder, state);
+WRAPPER(GstVideoDecoder, reset, int, (void* decoder, int hard), "pi", decoder, hard);
+WRAPPER(GstVideoDecoder, finish, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, handle_frame, int, (void* decoder, void* frame), "pp", decoder, frame);
+WRAPPER(GstVideoDecoder, sink_event, int, (void* decoder, void* event), "pp", decoder, event);
+WRAPPER(GstVideoDecoder, src_event, int, (void* decoder, void* event), "pp", decoder, event);
+WRAPPER(GstVideoDecoder, negotiate, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, decide_allocation, int, (void* decoder, void* query), "pp", decoder, query);
+WRAPPER(GstVideoDecoder, propose_allocation, int, (void* decoder, void* query), "pp", decoder, query);
+WRAPPER(GstVideoDecoder, flush, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, sink_query, int, (void* decoder, void* query), "pp", decoder, query);
+WRAPPER(GstVideoDecoder, src_query, int, (void* decoder, void* query), "pp", decoder, query);
+WRAPPER(GstVideoDecoder, getcaps, void*, (void* decoder, void* filter), "pp", decoder, filter);
+WRAPPER(GstVideoDecoder, drain, int, (void* decoder), "p", decoder);
+WRAPPER(GstVideoDecoder, transform_meta, int, (void* decoder, void* frame, void* meta), "ppp", decoder, frame, meta);
+WRAPPER(GstVideoDecoder, handle_missing_data, int, (void* decoder, uint64_t timestamp, uint64_t duration), "pUU", decoder, timestamp, duration);
+
+#define SUPERGO() \
+ GO(open, iFp); \
+ GO(close, iFp); \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(parse, iFpppi); \
+ GO(set_format, iFpp); \
+ GO(reset, iFp); \
+ GO(finish, iFp); \
+ GO(handle_frame, iFpp); \
+ GO(sink_event, iFpp); \
+ GO(src_event, iFpp); \
+ GO(negotiate, iFp); \
+ GO(decide_allocation, iFpp); \
+ GO(propose_allocation, iFpp); \
+ GO(flush, iFp); \
+ GO(sink_query, iFpp); \
+ GO(src_query, iFpp); \
+ GO(getcaps, pFpp); \
+ GO(drain, iFp); \
+ GO(transform_meta, iFppp); \
+ GO(handle_missing_data, iFpUU); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoDecoderClass(my_GstVideoDecoderClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoDecoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoDecoderClass(my_GstVideoDecoderClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoDecoder (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoDecoderClass(my_GstVideoDecoderClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoDecoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGstVideoDecoderInstance(my_GstVideoDecoder_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstVideoDecoderInstance(my_GstVideoDecoder_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstVideoEncoderClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoEncoder, open, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, close, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, start, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, stop, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, set_format, int, (void* encoder, void* state), "pp", encoder, state);
+WRAPPER(GstVideoEncoder, handle_frame, int, (void* encoder, void* frame), "pp", encoder, frame);
+WRAPPER(GstVideoEncoder, reset, int, (void* encoder, int hard), "pi", encoder, hard);
+WRAPPER(GstVideoEncoder, finish, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, pre_push, int, (void* encoder, void* frame), "pp", encoder, frame);
+WRAPPER(GstVideoEncoder, getcaps, void*, (void* encoder, void* filter), "pp", encoder, filter);
+WRAPPER(GstVideoEncoder, sink_event, int, (void* encoder, void* event), "pp", encoder, event);
+WRAPPER(GstVideoEncoder, src_event, int, (void* encoder, void* event), "pp", encoder, event);
+WRAPPER(GstVideoEncoder, negotiate, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, decide_allocation, int, (void* encoder, void* query), "pp", encoder, query);
+WRAPPER(GstVideoEncoder, propose_allocation, int, (void* encoder, void* query), "pp", encoder, query);
+WRAPPER(GstVideoEncoder, flush, int, (void* encoder), "p", encoder);
+WRAPPER(GstVideoEncoder, sink_query, int, (void* encoder, void* query), "pp", encoder, query);
+WRAPPER(GstVideoEncoder, src_query, int, (void* encoder, void* query), "pp", encoder, query);
+WRAPPER(GstVideoEncoder, transform_meta, int, (void* encoder, void* frame, void* meta), "ppp", encoder, frame, meta);
+
+#define SUPERGO() \
+ GO(open, iFp); \
+ GO(close, iFp); \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(set_format, iFpp); \
+ GO(handle_frame, iFpp); \
+ GO(reset, iFp); \
+ GO(finish, iFp); \
+ GO(pre_push, iFpp); \
+ GO(getcaps, pFpp); \
+ GO(sink_event, iFpp); \
+ GO(src_event, iFpp); \
+ GO(negotiate, iFp); \
+ GO(decide_allocation, iFpp); \
+ GO(propose_allocation, iFpp); \
+ GO(flush, iFp); \
+ GO(sink_query, iFpp); \
+ GO(src_query, iFpp); \
+ GO(transform_meta, iFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoEncoderClass(my_GstVideoEncoderClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoEncoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoEncoderClass(my_GstVideoEncoderClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoEncoder (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoEncoderClass(my_GstVideoEncoderClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoEncoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
+
+static void unwrapGstVideoEncoderInstance(my_GstVideoEncoder_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstVideoEncoderInstance(my_GstVideoEncoder_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstBaseSinkClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstBaseSink, get_caps, void*, (void* sink, void* filter), "pp", sink, filter);
+WRAPPER(GstBaseSink, set_caps, int, (void* sink, void* caps), "pp", sink, caps);
+WRAPPER(GstBaseSink, fixate, void* , (void* sink, void* caps), "pp", sink, caps);
+WRAPPER(GstBaseSink, activate_pull, int, (void* sink, int active), "pi", sink, active);
+WRAPPER(GstBaseSink, get_times, void, (void* sink, void* buffer, void* start, void* end), "pppp", sink, buffer, start, end);
+WRAPPER(GstBaseSink, propose_allocation, int, (void* sink, void* query), "pp", sink, query);
+WRAPPER(GstBaseSink, start, int, (void* sink), "p", sink);
+WRAPPER(GstBaseSink, stop, int, (void* sink), "p", sink);
+WRAPPER(GstBaseSink, unlock, int, (void* sink), "p", sink);
+WRAPPER(GstBaseSink, unlock_stop, int, (void* sink), "p", sink);
+WRAPPER(GstBaseSink, query, int, (void* sink, void* query), "pp", sink, query);
+WRAPPER(GstBaseSink, event, int, (void* sink, void* event), "pp", sink, event);
+WRAPPER(GstBaseSink, wait_event, int, (void* sink, void* event), "pp", sink, event);
+WRAPPER(GstBaseSink, prepare, int, (void* sink, void* buffer), "pp", sink, buffer);
+WRAPPER(GstBaseSink, prepare_list, int, (void* sink, void* buffer_list), "pp", sink, buffer_list);
+WRAPPER(GstBaseSink, preroll, int, (void* sink, void* buffer), "pp", sink, buffer);
+WRAPPER(GstBaseSink, render, int, (void* sink, void* buffer), "pp", sink, buffer);
+WRAPPER(GstBaseSink, render_list, int, (void* sink, void* buffer_list), "pp", sink, buffer_list);
+
+#define SUPERGO() \
+ GO(get_caps, pFpp); \
+ GO(set_caps, iFpp); \
+ GO(fixate, pFpp); \
+ GO(activate_pull, iFpi); \
+ GO(get_times, vFpppp); \
+ GO(propose_allocation, iFpp); \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(unlock, iFp); \
+ GO(unlock_stop, iFp); \
+ GO(query, iFpp); \
+ GO(event, iFpp); \
+ GO(wait_event, iFpp); \
+ GO(prepare, iFpp); \
+ GO(prepare_list, iFpp); \
+ GO(preroll, iFpp); \
+ GO(render, iFpp); \
+ GO(render_list, iFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstBaseSinkClass(my_GstBaseSinkClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstBaseSink (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstBaseSinkClass(my_GstBaseSinkClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstBaseSink (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstBaseSinkClass(my_GstBaseSinkClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstBaseSink (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstBaseSinkInstance(my_GstBaseSink_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstBaseSinkInstance(my_GstBaseSink_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstVideoSinkClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoSink, show_frame, int, (void* video_sink, void* buf), "pp", video_sink, buf);
+WRAPPER(GstVideoSink, set_info, int, (void* video_sink, void* caps, void* info), "ppp", video_sink, caps, info);
+
+#define SUPERGO() \
+ GO(show_frame, iFpp); \
+ GO(set_info, iFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoSinkClass(my_GstVideoSinkClass_t* class)
+{
+ wrapGstBaseSinkClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoSink (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoSinkClass(my_GstVideoSinkClass_t* class)
+{
+ unwrapGstBaseSinkClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoSink (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoSinkClass(my_GstVideoSinkClass_t* class)
+{
+ bridgeGstBaseSinkClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoSink (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstVideoSinkInstance(my_GstVideoSink_t* class)
+{
+ unwrapGstBaseSinkInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstVideoSinkInstance(my_GstVideoSink_t* class)
+{
+ bridgeGstBaseSinkInstance(&class->parent);
+}
+// ----- GstGLBaseFilterClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstGLBaseFilter, gl_start, int, (void* filter), "p", filter);
+WRAPPER(GstGLBaseFilter, gl_stop, void, (void* filter), "p", filter);
+WRAPPER(GstGLBaseFilter, gl_set_caps, int, (void* filter, void* incaps, void* outcaps), "ppp", filter, incaps, outcaps);
+
+#define SUPERGO() \
+ GO(gl_start, iFp); \
+ GO(gl_stop, vFp); \
+ GO(gl_set_caps, iFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstGLBaseFilterClass(my_GstGLBaseFilterClass_t* class)
+{
+ wrapGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstGLBaseFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstGLBaseFilterClass(my_GstGLBaseFilterClass_t* class)
+{
+ unwrapGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstGLBaseFilter (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstGLBaseFilterClass(my_GstGLBaseFilterClass_t* class)
+{
+ bridgeGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstGLBaseFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstGLBaseFilterInstance(my_GstGLBaseFilter_t* class)
+{
+ unwrapGstBaseTransformInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstGLBaseFilterInstance(my_GstGLBaseFilter_t* class)
+{
+ bridgeGstBaseTransformInstance(&class->parent);
+}
+// ----- GstGLFilterClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstGLFilter, set_caps, int, (void* filter, void* incaps, void* outcaps), "ppp", filter, incaps, outcaps);
+WRAPPER(GstGLFilter, filter, int, (void* filter, void* inbuf, void* outbuf), "ppp", filter, inbuf, outbuf);
+WRAPPER(GstGLFilter, filter_texture, int, (void* filter, void* input, void* output), "ppp", filter, input, output);
+WRAPPER(GstGLFilter, init_fbo, int, (void* filter), "p", filter);
+WRAPPER(GstGLFilter, transform_internal_caps, void*, (void* filter, int direction, void* caps, void* filter_caps), "pipp", filter, direction, caps, filter_caps);
+
+#define SUPERGO() \
+ GO(set_caps, iFppp); \
+ GO(filter, iFppp); \
+ GO(filter_texture, iFppp); \
+ GO(init_fbo, iFp); \
+ GO(transform_internal_caps, pFpipp);\
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstGLFilterClass(my_GstGLFilterClass_t* class)
+{
+ wrapGstGLBaseFilterClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstGLFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstGLFilterClass(my_GstGLFilterClass_t* class)
+{
+ unwrapGstGLBaseFilterClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstGLFilter (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstGLFilterClass(my_GstGLFilterClass_t* class)
+{
+ bridgeGstGLBaseFilterClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstGLFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstGLFilterInstance(my_GstGLFilter_t* class)
+{
+ unwrapGstGLBaseFilterInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstGLFilterInstance(my_GstGLFilter_t* class)
+{
+ bridgeGstGLBaseFilterInstance(&class->parent);
+}
+// ----- GstAggregatorClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstAggregator, flush, int, (void* self), "p", self);
+WRAPPER(GstAggregator, clip, void*, (void* self, void* aggregator_pad, void* buf), "ppp", self, aggregator_pad, buf);
+WRAPPER(GstAggregator, finish_buffer, int, (void* self, void* buffer), "pp", self, buffer);
+WRAPPER(GstAggregator, sink_event, int, (void* self, void* aggregator_pad, void* event), "ppp", self, aggregator_pad, event);
+WRAPPER(GstAggregator, sink_query, int, (void* self, void* aggregator_pad, void* query), "ppp", self, aggregator_pad, query);
+WRAPPER(GstAggregator, src_event, int, (void* self, void* event), "pp", self, event);
+WRAPPER(GstAggregator, src_query, int, (void* self, void* query), "pp", self, query);
+WRAPPER(GstAggregator, src_activate, int, (void* self, int mode, int active), "pii", self, mode, active);
+WRAPPER(GstAggregator, aggregate, int, (void* self, int timeout), "pi", self, timeout);
+WRAPPER(GstAggregator, stop, int, (void* self), "p", self);
+WRAPPER(GstAggregator, start, int, (void* self), "p", self);
+WRAPPER(GstAggregator, get_next_time, uint64_t, (void* self), "p", self);
+WRAPPER(GstAggregator, create_new_pad, void*, (void* self, void* templ, void* req_name, void* caps), "pppp", self, templ, req_name, caps);
+WRAPPER(GstAggregator, update_src_caps, int, (void* self, void* caps, void* ret), "ppp", self, caps, ret);
+WRAPPER(GstAggregator, fixate_src_caps, void*, (void* self, void* caps), "pp", self, caps);
+WRAPPER(GstAggregator, negotiated_src_caps, int, (void* self, void* caps), "pp", self, caps);
+WRAPPER(GstAggregator, decide_allocation, int, (void* self, void* query), "pp", self, query);
+WRAPPER(GstAggregator, propose_allocation, int, (void* self, void* pad, void* decide_query, void* query), "pppp", self, pad, decide_query, query);
+WRAPPER(GstAggregator, negotiate, int, (void* self), "p", self);
+WRAPPER(GstAggregator, sink_event_pre_queue, int, (void* self, void* aggregator_pad, void* event), "ppp", self, aggregator_pad, event);
+WRAPPER(GstAggregator, sink_query_pre_queue, int, (void* self, void* aggregator_pad, void* query), "ppp", self, aggregator_pad, query);
+WRAPPER(GstAggregator, finish_buffer_list, int, (void* self, void* bufferlist), "pp", self, bufferlist);
+WRAPPER(GstAggregator, peek_next_sample, void, (void* self, void* aggregator_pad), "pp", self, aggregator_pad);
+
+#define SUPERGO() \
+ GO(flush, iFp); \
+ GO(clip, pFppp); \
+ GO(finish_buffer, iFpp); \
+ GO(sink_event, iFppp); \
+ GO(sink_query, iFppp); \
+ GO(src_event, iFpp); \
+ GO(src_query, iFpp); \
+ GO(src_activate, iFpii); \
+ GO(aggregate, iFpi); \
+ GO(stop, iFp); \
+ GO(start, iFp); \
+ GO(get_next_time, UFp); \
+ GO(create_new_pad, pFpppp); \
+ GO(update_src_caps, iFppp); \
+ GO(fixate_src_caps, pFpp); \
+ GO(negotiated_src_caps, iFpp); \
+ GO(decide_allocation, iFpp); \
+ GO(propose_allocation, iFpppp); \
+ GO(negotiate, iFp); \
+ GO(sink_event_pre_queue, iFppp); \
+ GO(sink_query_pre_queue, iFppp); \
+ GO(finish_buffer_list, iFpp); \
+ GO(peek_next_sample, vFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstAggregatorClass(my_GstAggregatorClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstAggregator (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstAggregatorClass(my_GstAggregatorClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstAggregator (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstAggregatorClass(my_GstAggregatorClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstAggregator (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstAggregatorInstance(my_GstAggregator_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstAggregatorInstance(my_GstAggregator_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstVideoAggregatorClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoAggregator, update_caps, void*, (void* vagg, void* caps), "pp", vagg, caps);
+WRAPPER(GstVideoAggregator, aggregate_frames, int, (void* vagg, void* outbuffer), "pp", vagg, outbuffer);
+WRAPPER(GstVideoAggregator, create_output_buffer, int, (void* vagg, void* outbuffer), "pp", vagg, outbuffer);
+WRAPPER(GstVideoAggregator, find_best_format, void, (void* vagg, void* downstream_caps, void* best_info, void* at_least_one_alpha), "pppp", vagg, downstream_caps, best_info, at_least_one_alpha);
+
+#define SUPERGO() \
+ GO(update_caps, pFpp); \
+ GO(aggregate_frames, iFpp); \
+ GO(create_output_buffer, iFpp); \
+ GO(find_best_format, vFpppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoAggregatorClass(my_GstVideoAggregatorClass_t* class)
+{
+ wrapGstAggregatorClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoAggregator (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoAggregatorClass(my_GstVideoAggregatorClass_t* class)
+{
+ unwrapGstAggregatorClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoAggregator (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoAggregatorClass(my_GstVideoAggregatorClass_t* class)
+{
+ bridgeGstAggregatorClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoAggregator (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstVideoAggregatorInstance(my_GstVideoAggregator_t* class)
+{
+ unwrapGstAggregatorInstance(&class->aggregator);
+}
+// autobridge
+static void bridgeGstVideoAggregatorInstance(my_GstVideoAggregator_t* class)
+{
+ bridgeGstAggregatorInstance(&class->aggregator);
+}
+// ----- GstPadClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstPad, linked, void, (void* pad, void* peer), "pp", pad, peer);
+WRAPPER(GstPad, unlinked, void, (void* pad, void* peer), "pp", pad, peer);
+
+#define SUPERGO() \
+ GO(linked, vFpp); \
+ GO(unlinked, vFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstPadClass(my_GstPadClass_t* class)
+{
+ wrapGstObjectClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstPadClass(my_GstPadClass_t* class)
+{
+ unwrapGstObjectClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstPad (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstPadClass(my_GstPadClass_t* class)
+{
+ bridgeGstObjectClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+WRAPPER(GstPadInstance, activatefunc, int , (void* pad, void* parent), "pp", pad, parent);
+WRAPPER(GstPadInstance, activatenotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, activatemodefunc, int , (void* pad, void* parent, int mode, int active), "ppii", pad, parent, mode, active);
+WRAPPER(GstPadInstance, activatemodenotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, linkfunc, int , (void* pad, void* parent, void* peer), "ppp", pad, parent, peer);
+WRAPPER(GstPadInstance, linknotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, unlinkfunc, void , (void* pad, void* parent), "pp", pad, parent);
+WRAPPER(GstPadInstance, unlinknotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, chainfunc, int , (void* pad, void* parent, void* buffer), "ppp", pad, parent, buffer);
+WRAPPER(GstPadInstance, chainnotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, chainlistfunc, int , (void* pad, void* parent, void* list), "ppp", pad, parent, list);
+WRAPPER(GstPadInstance, chainlistnotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, getrangefunc, int , (void* pad, void* parent, uint64_t offset, uint32_t length, void* buffer), "ppUup", pad, parent, offset, length, buffer);
+WRAPPER(GstPadInstance, getrangenotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, eventfunc, int , (void* pad, void* parent, void* event), "ppp", pad, parent, event);
+WRAPPER(GstPadInstance, eventnotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, queryfunc, int , (void* pad, void* parent, void* query), "ppp", pad, parent, query);
+WRAPPER(GstPadInstance, querynotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, iterintlinkfunc, void* , (void* pad, void* parent), "pp", pad, parent);
+WRAPPER(GstPadInstance, iterintlinknotify, void , (void* a), "p", a);
+WRAPPER(GstPadInstance, finalize_hook, void , (void* hook_list, void* hook), "pp", hook_list, hook);
+WRAPPER(GstPadInstance, eventfullfunc, int , (void* pad, void* parent, void* event), "ppp", pad, parent, event);
+
+#define SUPERGO() \
+ GO(activatefunc, iFpp); \
+ GO(activatenotify, vFp); \
+ GO(activatemodefunc, iFppii); \
+ GO(activatemodenotify, vFp); \
+ GO(linkfunc, iFppp); \
+ GO(linknotify, vFp); \
+ GO(unlinkfunc, vFpp); \
+ GO(unlinknotify, vFp); \
+ GO(chainfunc, iFppp); \
+ GO(chainnotify, vFp); \
+ GO(chainlistfunc, iFppp); \
+ GO(chainlistnotify, vFp); \
+ GO(getrangefunc, iFppUup); \
+ GO(getrangenotify, vFp); \
+ GO(eventfunc, iFppp); \
+ GO(eventnotify, vFp); \
+ GO(queryfunc, iFppp); \
+ GO(querynotify, vFp); \
+ GO(iterintlinkfunc, pFpp); \
+ GO(iterintlinknotify, vFp); \
+ GO2(probes, finalize_hook, vFpp); \
+ GO2(ABI.abi, eventfullfunc, vFppp); \
+
+static void unwrapGstPadInstance(my_GstPad_t* class)
+{
+ unwrapGstObjectInstance(&class->parent);
+ #define GO(A, W) class->A = find_##A##_GstPadInstance (class->A)
+ #define GO2(B, A, W) class->B.A = find_##A##_GstPadInstance (class->B.A)
+ SUPERGO()
+ #undef GO2
+ #undef GO
+}
+// autobridge
+static void bridgeGstPadInstance(my_GstPad_t* class)
+{
+ bridgeGstObjectInstance(&class->parent);
+ #define GO(A, W) autobridge_##A##_GstPadInstance (W, class->A)
+ #define GO2(B, A, W) autobridge_##A##_GstPadInstance (W, class->B.A)
+ SUPERGO()
+ #undef GO2
+ #undef GO
+}
+#undef SUPERGO
+// ----- GstAggregatorPadClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstAggregatorPad, flush, int, (void* aggpad, void* aggregator), "pp", aggpad, aggregator);
+WRAPPER(GstAggregatorPad, skip_buffer, int, (void* aggpad, void* aggregator, void* buffer), "ppp", aggpad, aggregator, buffer);
+
+#define SUPERGO() \
+ GO(flush, iFpp); \
+ GO(skip_buffer, iFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstAggregatorPadClass(my_GstAggregatorPadClass_t* class)
+{
+ wrapGstPadClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstAggregatorPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstAggregatorPadClass(my_GstAggregatorPadClass_t* class)
+{
+ unwrapGstPadClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstAggregatorPad (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstAggregatorPadClass(my_GstAggregatorPadClass_t* class)
+{
+ bridgeGstPadClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstAggregatorPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstAggregatorPadInstance(my_GstAggregatorPad_t* class)
+{
+ unwrapGstPadInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstAggregatorPadInstance(my_GstAggregatorPad_t* class)
+{
+ bridgeGstPadInstance(&class->parent);
+}
+// ----- GstVideoAggregatorPadClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoAggregatorPad, update_conversion_info, void, (void* pad), "p", pad);
+WRAPPER(GstVideoAggregatorPad, prepare_frame, int, (void* pad, void* vagg, void* buffer, void* prepared_frame), "pppp", pad, vagg, buffer, prepared_frame);
+WRAPPER(GstVideoAggregatorPad, clean_frame, void, (void* pad, void* vagg, void* prepared_frame), "ppp", pad, vagg, prepared_frame);
+WRAPPER(GstVideoAggregatorPad, prepare_frame_start, void, (void* pad, void* vagg, void* buffer, void* prepared_frame), "pppp", pad, vagg, buffer, prepared_frame);
+WRAPPER(GstVideoAggregatorPad, prepare_frame_finish, void, (void* pad, void* vagg, void* prepared_frame), "ppp", pad, vagg, prepared_frame);
+
+#define SUPERGO() \
+ GO(update_conversion_info, vFp); \
+ GO(prepare_frame, iFpppp); \
+ GO(clean_frame, vFppp); \
+ GO(prepare_frame_start, vFpppp); \
+ GO(prepare_frame_finish, vFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoAggregatorPadClass(my_GstVideoAggregatorPadClass_t* class)
+{
+ wrapGstAggregatorPadClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoAggregatorPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoAggregatorPadClass(my_GstVideoAggregatorPadClass_t* class)
+{
+ unwrapGstAggregatorPadClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoAggregatorPad (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoAggregatorPadClass(my_GstVideoAggregatorPadClass_t* class)
+{
+ bridgeGstAggregatorPadClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoAggregatorPad (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstVideoAggregatorPadInstance(my_GstVideoAggregatorPad_t* class)
+{
+ unwrapGstAggregatorPadInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstVideoAggregatorPadInstance(my_GstVideoAggregatorPad_t* class)
+{
+ bridgeGstAggregatorPadInstance(&class->parent);
+}
+#undef SUPERGO
+// ----- GstBaseSrcClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstBaseSrc, get_caps, void*, (void* src, void* filter), "pp", src, filter);
+WRAPPER(GstBaseSrc, negotiate, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, fixate, void*, (void* src, void* caps), "pp", src, caps);
+WRAPPER(GstBaseSrc, set_caps, int, (void* src, void* caps), "pp", src, caps);
+WRAPPER(GstBaseSrc, decide_allocation, int, (void* src, void* query), "pp", src, query);
+WRAPPER(GstBaseSrc, start, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, stop, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, get_times, void , (void* src, void* buffer, void* start, void* end), "pppp", src, buffer, start, end);
+WRAPPER(GstBaseSrc, get_size, int, (void* src, void* size), "pp", src, size);
+WRAPPER(GstBaseSrc, is_seekable, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, prepare_seek_segment, int, (void* src, void* seek, void* segment), "ppp", src, seek, segment);
+WRAPPER(GstBaseSrc, do_seek, int, (void* src, void* segment), "pp", src, segment);
+WRAPPER(GstBaseSrc, unlock, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, unlock_stop, int, (void* src), "p", src);
+WRAPPER(GstBaseSrc, query, int, (void* src, void* query), "pp", src, query);
+WRAPPER(GstBaseSrc, event, int, (void* src, void* event), "pp", src, event);
+WRAPPER(GstBaseSrc, create, int, (void* src, uint64_t offset, uint32_t size, void* buf), "pUup", src, offset, size, buf);
+WRAPPER(GstBaseSrc, alloc, int, (void* src, uint64_t offset, uint32_t size, void* buf), "pUup", src, offset, size, buf);
+WRAPPER(GstBaseSrc, fill, int, (void* src, uint64_t offset, uint32_t size, void* buf), "pUup", src, offset, size, buf);
+
+#define SUPERGO() \
+ GO(get_caps, pFpp); \
+ GO(negotiate, iFp); \
+ GO(fixate, pFpp); \
+ GO(set_caps, iFpp); \
+ GO(decide_allocation, iFpp); \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(get_times, vFpppp); \
+ GO(get_size, iFpp); \
+ GO(is_seekable, iFp); \
+ GO(prepare_seek_segment, iFppp); \
+ GO(do_seek, iFpp); \
+ GO(unlock, iFp); \
+ GO(unlock_stop, iFp); \
+ GO(query, iFpp); \
+ GO(event, iFpp); \
+ GO(create, iFpUup); \
+ GO(alloc, iFpUup); \
+ GO(fill, iFpUup); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstBaseSrcClass(my_GstBaseSrcClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstBaseSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstBaseSrcClass(my_GstBaseSrcClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstBaseSrc (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstBaseSrcClass(my_GstBaseSrcClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstBaseSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstBaseSrcInstance(my_GstBaseSrc_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstBaseSrcInstance(my_GstBaseSrc_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstPushSrcClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstPushSrc, create, int, (void* src, void* buf), "pp", src, buf);
+WRAPPER(GstPushSrc, alloc, int, (void* src, void* buf), "pp", src, buf);
+WRAPPER(GstPushSrc, fill, int, (void* src, void* buf), "pp", src, buf);
+
+#define SUPERGO() \
+ GO(create, iFpp); \
+ GO(alloc, iFpp); \
+ GO(fill, iFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstPushSrcClass(my_GstPushSrcClass_t* class)
+{
+ wrapGstBaseSrcClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstPushSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstPushSrcClass(my_GstPushSrcClass_t* class)
+{
+ unwrapGstBaseSrcClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstPushSrc (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstPushSrcClass(my_GstPushSrcClass_t* class)
+{
+ bridgeGstBaseSrcClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstPushSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstPushSrcInstance(my_GstPushSrc_t* class)
+{
+ unwrapGstBaseSrcInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstPushSrcInstance(my_GstPushSrc_t* class)
+{
+ bridgeGstBaseSrcInstance(&class->parent);
+}
+// ----- GstGLBaseSrcClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstGLBaseSrc, gl_start, int, (void* src), "p", src);
+WRAPPER(GstGLBaseSrc, gl_stop, void, (void* src), "p", src);
+WRAPPER(GstGLBaseSrc, fill_gl_memory, int, (void* src, void* mem), "pp", src, mem);
+
+#define SUPERGO() \
+ GO(gl_start, iFp); \
+ GO(gl_stop, vFp); \
+ GO(fill_gl_memory, iFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstGLBaseSrcClass(my_GstGLBaseSrcClass_t* class)
+{
+ wrapGstPushSrcClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstGLBaseSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstGLBaseSrcClass(my_GstGLBaseSrcClass_t* class)
+{
+ unwrapGstPushSrcClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstGLBaseSrc (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstGLBaseSrcClass(my_GstGLBaseSrcClass_t* class)
+{
+ bridgeGstPushSrcClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstGLBaseSrc (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstGLBaseSrcInstance(my_GstGLBaseSrc_t* class)
+{
+ unwrapGstPushSrcInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstGLBaseSrcInstance(my_GstGLBaseSrc_t* class)
+{
+ bridgeGstPushSrcInstance(&class->parent);
+}
+// ----- GstAudioDecoderClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstAudioDecoder, start, int,(void* dec), "p", dec);
+WRAPPER(GstAudioDecoder, stop, int,(void* dec), "p", dec);
+WRAPPER(GstAudioDecoder, set_format, int,(void* dec, void* caps), "pp", dec, caps);
+WRAPPER(GstAudioDecoder, parse, int,(void* dec, void* adapter, void* offset, void* length), "pppp", dec, adapter, offset, length);
+WRAPPER(GstAudioDecoder, handle_frame, int,(void* dec, void* buffer), "pp", dec, buffer);
+WRAPPER(GstAudioDecoder, flush, void ,(void* dec, int hard), "pi", dec, hard);
+WRAPPER(GstAudioDecoder, pre_push, int,(void* dec, void* buffer), "pp", dec, buffer);
+WRAPPER(GstAudioDecoder, sink_event, int,(void* dec, void* event), "pp", dec, event);
+WRAPPER(GstAudioDecoder, src_event, int,(void* dec, void* event), "pp", dec, event);
+WRAPPER(GstAudioDecoder, open, int,(void* dec), "p", dec);
+WRAPPER(GstAudioDecoder, close, int,(void* dec), "p", dec);
+WRAPPER(GstAudioDecoder, negotiate, int,(void* dec), "p", dec);
+WRAPPER(GstAudioDecoder, decide_allocation, int,(void* dec, void* query), "pp", dec, query);
+WRAPPER(GstAudioDecoder, propose_allocation, int,(void* dec, void* query), "pp", dec, query);
+WRAPPER(GstAudioDecoder, sink_query, int,(void* dec, void* query), "pp", dec, query);
+WRAPPER(GstAudioDecoder, src_query, int,(void* dec, void* query), "pp", dec, query);
+WRAPPER(GstAudioDecoder, getcaps, void*,(void* dec, void* filter), "pp", dec, filter);
+WRAPPER(GstAudioDecoder, transform_meta, int,(void* enc, void* outbuf, void* meta, void* inbuf), "pppp", enc, outbuf, meta, inbuf);
+
+#define SUPERGO() \
+ GO(start, iFp); \
+ GO(stop, iFp); \
+ GO(set_format, iFpp); \
+ GO(parse, iFpppp); \
+ GO(handle_frame, iFpp); \
+ GO(flush, vFpi); \
+ GO(pre_push, iFpp); \
+ GO(sink_event, iFpp); \
+ GO(src_event, iFpp); \
+ GO(open, iFp); \
+ GO(close, iFp); \
+ GO(negotiate, iFp); \
+ GO(decide_allocation, iFpp); \
+ GO(propose_allocation, iFpp); \
+ GO(sink_query, iFpp); \
+ GO(src_query, iFpp); \
+ GO(getcaps, vFpp); \
+ GO(transform_meta, iFpppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstAudioDecoderClass(my_GstAudioDecoderClass_t* class)
+{
+ wrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstAudioDecoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstAudioDecoderClass(my_GstAudioDecoderClass_t* class)
+{
+ unwrapGstElementClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstAudioDecoder (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstAudioDecoderClass(my_GstAudioDecoderClass_t* class)
+{
+ bridgeGstElementClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstAudioDecoder (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstAudioDecoderInstance(my_GstAudioDecoder_t* class)
+{
+ unwrapGstElementInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstAudioDecoderInstance(my_GstAudioDecoder_t* class)
+{
+ bridgeGstElementInstance(&class->parent);
+}
+// ----- GstVideoFilterClass ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstVideoFilter, set_info, int, (void* filter, void* incaps, void* in_info, void* outcaps, void* out_info), "ppppp", filter, incaps, in_info, outcaps, out_info);
+WRAPPER(GstVideoFilter, transform_frame, int, (void* filter, void* inframe, void* outframe), "ppp", filter, inframe, outframe);
+WRAPPER(GstVideoFilter, transform_frame_ip, int, (void* filter, void* frame), "pp", filter, frame);
+
+#define SUPERGO() \
+ GO(set_info, iFppppp); \
+ GO(transform_frame, iFppp); \
+ GO(transform_frame_ip, iFpp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstVideoFilterClass(my_GstVideoFilterClass_t* class)
+{
+ wrapGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) class->A = reverse_##A##_GstVideoFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstVideoFilterClass(my_GstVideoFilterClass_t* class)
+{
+ unwrapGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) class->A = find_##A##_GstVideoFilter (class->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstVideoFilterClass(my_GstVideoFilterClass_t* class)
+{
+ bridgeGstBaseTransformClass(&class->parent_class);
+ #define GO(A, W) autobridge_##A##_GstVideoFilter (W, class->A)
+ SUPERGO()
+ #undef GO
+}
+#undef SUPERGO
+
+static void unwrapGstVideoFilterInstance(my_GstVideoFilter_t* class)
+{
+ unwrapGstBaseTransformInstance(&class->parent);
+}
+// autobridge
+static void bridgeGstVideoFilterInstance(my_GstVideoFilter_t* class)
+{
+ bridgeGstBaseTransformInstance(&class->parent);
+}
// ----- GDBusProxyClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GDBusProxy, g_properties_changed, void, (void* proxy, void* changed_properties, const char* const* invalidated_properties), "ppp", proxy, changed_properties, invalidated_properties);
@@ -2476,15 +4454,86 @@ static void bridgeGDBusProxyClass(my_GDBusProxyClass_t* class)
#undef SUPERGO
+static void unwrapGDBusProxyInstance(my_GDBusProxy_t* class)
+{
+ unwrapGObjectInstance(&class->parent);
+}
+// autobridge
+static void bridgeGDBusProxyInstance(my_GDBusProxy_t* class)
+{
+ bridgeGObjectInstance(&class->parent);
+}
+// ----- GstURIHandlerInterface ------
+// wrapper x86 -> natives of callbacks
+WRAPPER(GstURIHandler,get_type, int, (size_t type), "L", type);
+WRAPPER(GstURIHandler,get_protocols, void*, (size_t type), "L", type);
+WRAPPER(GstURIHandler,get_uri, void*, (void* handler), "p", handler);
+WRAPPER(GstURIHandler,set_uri, int, (void* handler, void* uri, void* error), "ppp", handler, uri, error);
+
+#define SUPERGO() \
+ GO(get_type, iFL); \
+ GO(get_protocols, pFL); \
+ GO(get_uri, pFp); \
+ GO(set_uri, iFppp); \
+
+// wrap (so bridge all calls, just in case)
+static void wrapGstURIHandlerInterface(my_GstURIHandlerInterface_t* iface)
+{
+ // parent don't need wrazpping
+ #define GO(A, W) iface->A = reverse_##A##_GstURIHandler (W, iface->A)
+ SUPERGO()
+ #undef GO
+}
+// unwrap (and use callback if not a native call anymore)
+static void unwrapGstURIHandlerInterface(my_GstURIHandlerInterface_t* iface)
+{
+ // parent don't need wrazpping
+ #define GO(A, W) iface->A = find_##A##_GstURIHandler (iface->A)
+ SUPERGO()
+ #undef GO
+}
+// autobridge
+static void bridgeGstURIHandlerInterface(my_GstURIHandlerInterface_t* iface)
+{
+ // parent don't need wrazpping
+ #define GO(A, W) autobridge_##A##_GstURIHandler (W, iface->A)
+ SUPERGO()
+ #undef GO
+}
+
+#undef SUPERGO
// No more wrap/unwrap
#undef WRAPPER
#undef FIND
#undef REVERSE
#undef WRAPPED
+// a class to collection of custom defined class...
+void addRegisteredClass(size_t klass, char* name)
+{
+ if(!klass)
+ return;
+ if(!my_customclass) {
+ my_customclass = kh_init(customclass);
+ }
+ khint_t k;
+ int ret;
+ k = kh_put(customclass, my_customclass, klass, &ret);
+ kh_value(my_customclass, k) = strdup(name);
+}
+
+int checkRegisteredClass(size_t klass)
+{
+ if(!my_customclass)
+ return 0;
+ khint_t k = kh_get(customclass, my_customclass, klass);
+ return (k==kh_end(my_customclass))?0:1;
+}
+
// g_type_class_peek_parent
static void wrapGTKClass(void* cl, size_t type)
{
+ #define GTKIFACE(A)
#define GTKCLASS(A) \
if(type==my_##A) \
wrap##A##Class((my_##A##Class_t*)cl); \
@@ -2498,13 +4547,15 @@ static void wrapGTKClass(void* cl, size_t type)
my_MetaFrames2 = type;
wrapMetaFrames2Class((my_MetaFrames2Class_t*)cl);
} else
- printf_log(LOG_NONE, "Warning, Custom Class initializer with unknown class type %zd (%s)\n", type, g_type_name(type));
+ printf_log(LOG_NONE, "Warning, Custom Class initializer with unknown class type 0w%zx (%s)\n", type, g_type_name(type));
}
#undef GTKCLASS
+ #undef GTKIFACE
}
static void unwrapGTKClass(void* cl, size_t type)
{
+ #define GTKIFACE(A)
#define GTKCLASS(A) \
if(type==my_##A) \
unwrap##A##Class((my_##A##Class_t*)cl); \
@@ -2516,10 +4567,12 @@ static void unwrapGTKClass(void* cl, size_t type)
else
{} // else no warning, one is enough...
#undef GTKCLASS
+ #undef GTKIFACE
}
static void bridgeGTKClass(void* cl, size_t type)
{
+ #define GTKIFACE(A)
#define GTKCLASS(A) \
if(type==my_##A) \
bridge##A##Class((my_##A##Class_t*)cl); \
@@ -2529,15 +4582,105 @@ static void bridgeGTKClass(void* cl, size_t type)
GTKCLASSES()
if(type==8) {} // GInterface have no structure
else {
- printf_log(LOG_NONE, "Warning, AutoBridge GTK Class with unknown class type %zd (%s)\n", type, g_type_name(type));
+ printf_log(LOG_NONE, "Warning, AutoBridge GTK Class with unknown class type 0w%zx (%s)\n", type, g_type_name(type));
+ }
+ #undef GTKCLASS
+ #undef GTKIFACE
+}
+
+static void wrapGTKInterface(void* cl, size_t type)
+{
+ #define GTKCLASS(A)
+ #define GTKIFACE(A) \
+ if(type==my_##A) \
+ wrap##A##Interface((my_##A##Interface_t*)cl); \
+ else
+
+ printf_log(LOG_DEBUG, "wrapGTKInterface(%p, %zd (%s))\n", cl, type, g_type_name(type));
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else {
+ printf_log(LOG_NONE, "Warning, Custom Interface initializer with unknown class type 0x%zx (%s)\n", type, g_type_name(type));
}
+ #undef GTKIFACE
#undef GTKCLASS
}
+void unwrapGTKInterface(void* cl, size_t type)
+{
+ #define GTKCLASS(A)
+ #define GTKIFACE(A) \
+ if(type==my_##A) \
+ unwrap##A##Interface((my_##A##Interface_t*)cl); \
+ else
+
+ printf_log(LOG_DEBUG, "unwrapGTKInterface(%p, %zd (%s))\n", cl, type, g_type_name(type));
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else
+ {} // else no warning, one is enough...
+ #undef GTKIFACE
+ #undef GTKCLASS
+}
+
+static void bridgeGTKInterface(void* cl, size_t type)
+{
+ #define GTKCLASS(A)
+ #define GTKIFACE(A) \
+ if(type==my_##A) \
+ bridge##A##Interface((my_##A##Interface_t*)cl); \
+ else
+
+ printf_log(LOG_DEBUG, "bridgeGTKInterface(%p, %zd (%s))\n", cl, type, g_type_name(type));
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else {
+ printf_log(LOG_NONE, "Warning, AutoBridge GTK Interface with unknown class type 0x%zx (%s)\n", type, g_type_name(type));
+ }
+ #undef GTKCLASS
+ #undef GTKIFACE
+}
+
+void unwrapGTKInstance(void* cl, size_t type)
+{
+ #define GTKIFACE(A)
+ #define GTKCLASS(A) \
+ if(type==my_##A) \
+ unwrap##A##Instance((my_##A##_t*)cl); \
+ else
+
+ printf_log(LOG_DEBUG, "unwrapGTKInstance(%p, %zd (%s))\n", cl, type, g_type_name(type));
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else
+ {} // else no warning, one is enough...
+ #undef GTKCLASS
+ #undef GTKIFACE
+}
+
+void bridgeGTKInstance(void* cl, size_t type)
+{
+ #define GTKIFACE(A)
+ #define GTKCLASS(A) \
+ if(type==my_##A) \
+ bridge##A##Instance((my_##A##_t*)cl); \
+ else
+
+ printf_log(LOG_DEBUG, "bridgeGTKInstance(%p, %zd (%s))\n", cl, type, g_type_name(type));
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else {
+ printf_log(LOG_NONE, "Warning, AutoBridge GTK Class with unknown class type 0w%zx (%s)\n", type, g_type_name(type));
+ }
+ #undef GTKCLASS
+ #undef GTKIFACE
+}
typedef union my_GClassAll_s {
#define GTKCLASS(A) my_##A##Class_t A;
+ #define GTKIFACE(A) my_##A##Interface_t A;
GTKCLASSES()
+ #undef GTKIFACE
#undef GTKCLASS
} my_GClassAll_t;
@@ -2551,19 +4694,23 @@ SUPER()
void* unwrapCopyGTKClass(void* klass, size_t type)
{
if(!klass) return klass;
+ if(checkRegisteredClass(type))
+ return klass;
#define GO(A) if(klass == my_gclassall_ref_##A) return &my_gclassall_##A;
SUPER()
#undef GO
// check if class is the exact type we know
size_t sz = 0;
+ #define GTKIFACE(A)
#define GTKCLASS(A) if(type==my_##A) sz = sizeof(my_##A##Class_t); else
GTKCLASSES()
if(type==8) {} // GInterface have no structure
else {
- printf_log(LOG_NONE, "Warning, unwrapCopyGTKClass called with unknown class type %zu (%s)\n", type, g_type_name(type));
+ printf_log(LOG_NONE, "Warning, unwrapCopyGTKClass called with unknown class type 0x%zx (%s)\n", type, g_type_name(type));
return klass;
}
#undef GTKCLASS
+ #undef GTKIFACE
my_GClassAll_t *newklass = NULL;
#define GO(A) if(!newklass && !my_gclassall_ref_##A) {my_gclassall_ref_##A = klass; newklass = &my_gclassall_##A;}
SUPER()
@@ -2577,6 +4724,39 @@ void* unwrapCopyGTKClass(void* klass, size_t type)
return newklass;
}
+void* unwrapCopyGTKInterface(void* iface, size_t type)
+{
+ if(!iface) return iface;
+ if(checkRegisteredClass(type))
+ return iface;
+ #define GO(A) if(iface == my_gclassall_ref_##A) return &my_gclassall_##A;
+ SUPER()
+ #undef GO
+ // check if class is the exact type we know
+ size_t sz = 0;
+ #define GTKIFACE(A) if(type==my_##A) sz = sizeof(my_##A##Interface_t); else
+ #define GTKCLASS(A)
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else {
+ printf_log(LOG_NONE, "Warning, unwrapCopyGTKInterface called with unknown class type 0x%zx (%s)\n", type, g_type_name(type));
+ return iface;
+ }
+ #undef GTKCLASS
+ #undef GTKIFACE
+ my_GClassAll_t *newiface = NULL;
+ #define GO(A) if(!newiface && !my_gclassall_ref_##A) {my_gclassall_ref_##A = iface; newiface = &my_gclassall_##A;}
+ SUPER()
+ #undef GO
+ if(!newiface) {
+ printf_log(LOG_NONE, "Warning: no more slot for unwrapCopyGTKInterface\n");
+ return iface;
+ }
+ memcpy(newiface, iface, sz);
+ unwrapGTKInterface(newiface, type);
+ return newiface;
+}
+
// gtk_type_class
#define GO(A) \
@@ -2588,12 +4768,15 @@ SUPER()
void* wrapCopyGTKClass(void* klass, size_t type)
{
if(!klass) return klass;
+ while(checkRegisteredClass(type))
+ type = g_type_parent(type);
printf_log(LOG_DEBUG, "wrapCopyGTKClass(%p, %zd (%s))\n", klass, type, g_type_name(type));
#define GO(A) if(klass == my_gclassallu_ref_##A) return &my_gclassallu_##A;
SUPER()
#undef GO
// check if class is the exact type we know
int sz = 0;
+ #define GTKIFACE(A)
#define GTKCLASS(A) if(type==my_##A) sz = sizeof(my_##A##Class_t); else
GTKCLASSES()
if(type==8) {} // GInterface have no structure
@@ -2606,21 +4789,41 @@ void* wrapCopyGTKClass(void* klass, size_t type)
return klass;
}
}
+ #undef GTKIFACE
#undef GTKCLASS
- my_GClassAll_t *newklass = NULL;
- #define GO(A) if(!newklass && !my_gclassallu_ref_##A) {my_gclassallu_ref_##A = klass; newklass = &my_gclassallu_##A;}
+ bridgeGTKClass(klass, type);
+ return klass;
+}
+
+void* wrapCopyGTKInterface(void* iface, size_t type)
+{
+ if(!iface) return iface;
+ while(checkRegisteredClass(type))
+ type = g_type_parent(type);
+ printf_log(LOG_DEBUG, "wrapCopyGTKInterface(%p, %zd (%s))\n", iface, type, g_type_name(type));
+ #define GO(A) if(iface == my_gclassallu_ref_##A) return &my_gclassallu_##A;
SUPER()
#undef GO
- if(!newklass) {
- printf_log(LOG_NONE, "Warning: no more slot for wrapCopyGTKClass\n");
- return klass;
+ // check if class is the exact type we know
+ int sz = 0;
+ #define GTKIFACE(A) if(type==my_##A) sz = sizeof(my_##A##Interface_t); else
+ #define GTKCLASS(A)
+ GTKCLASSES()
+ if(type==8) {} // GInterface have no structure
+ else {
+ if(my_MetaFrames2==-1 && !strcmp(g_type_name(type), "MetaFrames")) {
+ my_MetaFrames2 = type;
+ sz = sizeof(my_MetaFrames2Class_t);
+ } else {
+ printf_log(LOG_NONE, "Warning, wrapCopyGTKInterface called with unknown class type 0x%zx (%s)\n", type, g_type_name(type));
+ return iface;
+ }
}
- memcpy(newklass, klass, sz);
- //wrapGTKClass(newklass, type);
- bridgeGTKClass(newklass, type);
- return newklass;
+ #undef GTKIFACE
+ #undef GTKCLASS
+ bridgeGTKInterface(iface, type);
+ return iface;
}
-
// ---- GTypeValueTable ----
// First the structure GTypeInfo statics, with paired x64 source pointer
@@ -3038,13 +5241,16 @@ static int my_class_init_##A(void* a, void* b) \
{ \
printf_log(LOG_DEBUG, "Custom Class init %d for class %p (parent=%p:%s)\n", A, a, (void*)parent_class_init_##A, g_type_name(parent_class_init_##A));\
int ret = RunFunctionFmt(my_class_init_fct_##A, "pp", a, b);\
- unwrapGTKClass(a, parent_class_init_##A); \
- bridgeGTKClass(a, parent_class_init_##A); \
+ size_t type = parent_class_init_##A; \
+ while(checkRegisteredClass(type)) \
+ type = g_type_parent(type); \
+ unwrapGTKClass(a, type); \
+ bridgeGTKClass(a, type); \
my_unwrap_signal_offset(a); \
- if(!strcmp(g_type_name(parent_class_init_##A), "AtkUtil")) { \
- my_AtkUtilClass_t* p = (my_AtkUtilClass_t*)g_type_class_peek(parent_class_init_##A);\
- unwrapGTKClass(p, parent_class_init_##A); \
- bridgeGTKClass(p, parent_class_init_##A); \
+ if(!strcmp(g_type_name(type), "AtkUtil")) { \
+ my_AtkUtilClass_t* p = (my_AtkUtilClass_t*)g_type_class_peek(type);\
+ unwrapGTKClass(p, type); \
+ bridgeGTKClass(p, type); \
} \
return ret; \
}
@@ -3088,20 +5294,28 @@ static void* find_class_finalize_Fct(void* fct)
// instance_init ...
#define GO(A) \
static uintptr_t my_instance_init_fct_##A = 0; \
+static size_t parent_instance_init_##A = 0; \
static int my_instance_init_##A(void* a, void* b) \
{ \
- return RunFunctionFmt(my_instance_init_fct_##A, "pp", a, b);\
+ printf_log(LOG_DEBUG, "Custom Instance init %d for class %p (parent=%p:%s)\n", A, a, (void*)parent_instance_init_##A, g_type_name(parent_instance_init_##A));\
+ int ret = RunFunctionFmt(my_instance_init_fct_##A, "pp", a, b); \
+ size_t type = parent_instance_init_##A; \
+ while(checkRegisteredClass(type)) \
+ type = g_type_parent(type); \
+ unwrapGTKInstance(a, type); \
+ bridgeGTKInstance(a, type); \
+ return ret; \
}
SUPER()
#undef GO
-static void* find_instance_init_Fct(void* fct)
+static void* find_instance_init_Fct(void* fct, size_t parent)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
- #define GO(A) if(my_instance_init_fct_##A == (uintptr_t)fct) return my_instance_init_##A;
+ #define GO(A) if(my_instance_init_fct_##A == (uintptr_t)fct && parent_instance_init_##A==parent) return my_instance_init_##A;
SUPER()
#undef GO
- #define GO(A) if(my_instance_init_fct_##A == 0) {my_instance_init_fct_##A = (uintptr_t)fct; return my_instance_init_##A; }
+ #define GO(A) if(my_instance_init_fct_##A == 0) {my_instance_init_fct_##A = (uintptr_t)fct; parent_instance_init_##A=parent; return my_instance_init_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for GTypeInfo instance_init callback\n");
@@ -3114,20 +5328,20 @@ my_GTypeInfo_t* findFreeGTypeInfo(my_GTypeInfo_t* fcts, size_t parent)
#define GO(A) if(used_gtypeinfo_##A && memcmp(&ref_gtypeinfo_##A, fcts, sizeof(my_GTypeInfo_t))==0) return &my_gtypeinfo_##A;
SUPER()
#undef GO
- #define GO(A) if(used_gtypeinfo_##A == 0) { \
- used_gtypeinfo_##A = 1; \
- memcpy(&ref_gtypeinfo_##A, fcts, sizeof(my_GTypeInfo_t)); \
- my_gtypeinfo_##A.class_size = fcts->class_size; \
- my_gtypeinfo_##A.base_init = find_base_init_Fct(fcts->base_init); \
- my_gtypeinfo_##A.base_finalize = find_base_finalize_Fct(fcts->base_finalize); \
- my_gtypeinfo_##A.class_init = find_class_init_Fct(fcts->class_init, parent); \
- my_gtypeinfo_##A.class_finalize = find_class_finalize_Fct(fcts->class_finalize);\
- my_gtypeinfo_##A.class_data = fcts->class_data; \
- my_gtypeinfo_##A.instance_size = fcts->instance_size; \
- my_gtypeinfo_##A.n_preallocs = fcts->n_preallocs; \
- my_gtypeinfo_##A.instance_init = find_instance_init_Fct(fcts->instance_init); \
- my_gtypeinfo_##A.value_table = findFreeGTypeValueTable(fcts->value_table); \
- return &my_gtypeinfo_##A; \
+ #define GO(A) if(used_gtypeinfo_##A == 0) { \
+ used_gtypeinfo_##A = 1; \
+ memcpy(&ref_gtypeinfo_##A, fcts, sizeof(my_GTypeInfo_t)); \
+ my_gtypeinfo_##A.class_size = fcts->class_size; \
+ my_gtypeinfo_##A.base_init = find_base_init_Fct(fcts->base_init); \
+ my_gtypeinfo_##A.base_finalize = find_base_finalize_Fct(fcts->base_finalize); \
+ my_gtypeinfo_##A.class_init = find_class_init_Fct(fcts->class_init, parent); \
+ my_gtypeinfo_##A.class_finalize = find_class_finalize_Fct(fcts->class_finalize); \
+ my_gtypeinfo_##A.class_data = fcts->class_data; \
+ my_gtypeinfo_##A.instance_size = fcts->instance_size; \
+ my_gtypeinfo_##A.n_preallocs = fcts->n_preallocs; \
+ my_gtypeinfo_##A.instance_init = find_instance_init_Fct(fcts->instance_init, parent); \
+ my_gtypeinfo_##A.value_table = findFreeGTypeValueTable(fcts->value_table); \
+ return &my_gtypeinfo_##A; \
}
SUPER()
#undef GO
@@ -3232,12 +5446,15 @@ void Set##A##ID(size_t id) \
{ \
my_##A = id; \
}
+#define GTKIFACE(A) GTKCLASS(A)
GTKCLASSES()
+#undef GTKIFACE
#undef GTKCLASS
void AutoBridgeGtk(void*(*ref)(size_t), void(*unref)(void*))
{
void* p;
+ #define GTKIFACE(A)
#define GTKCLASS(A) \
if(my_##A && my_##A!=-1) { \
p = ref(my_##A); \
@@ -3245,6 +5462,7 @@ void AutoBridgeGtk(void*(*ref)(size_t), void(*unref)(void*))
unref(p); \
}
GTKCLASSES()
+ #undef GTKIFACE
#undef GTKCLASS
}
@@ -3258,6 +5476,11 @@ void SetGClassPeek(void* f)
g_type_class_peek = f;
}
+void SetGTypeParent(void* f)
+{
+ g_type_parent = f;
+}
+
my_signal_t* new_mysignal(void* f, void* data, void* destroy)
{
my_signal_t* sig = (my_signal_t*)box_calloc(1, sizeof(my_signal_t));
diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c
index c80a531..258fb99 100644
--- a/src/tools/my_cpuid.c
+++ b/src/tools/my_cpuid.c
@@ -11,7 +11,6 @@
int get_cpuMhz()
{
int MHz = 0;
-#ifdef __arm__
FILE *f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
if(f) {
int r;
@@ -19,18 +18,133 @@ int get_cpuMhz()
MHz = r/1000;
fclose(f);
}
-#endif
+ if(!MHz) {
+ // try with lscpu, grabbing the max frequency
+ FILE* f = popen("lscpu | grep \"CPU max MHz:\" | sed -r 's/CPU max MHz:\\s{1,}//g'", "r");
+ if(f) {
+ char tmp[200] = "";
+ ssize_t s = fread(tmp, 1, 200, f);
+ pclose(f);
+ if(s>0) {
+ // worked! (unless it's saying "lscpu: command not found" or something like that)
+ if(!strstr(tmp, "lscpu")) {
+ // trim ending
+ while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
+ tmp[strlen(tmp)-1] = 0;
+ // incase multiple cpu type are present, there will be multiple lines
+ while(strchr(tmp, '\n'))
+ *strchr(tmp,'\n') = ' ';
+ // cut the float part (so '.' or ','), it's not needed
+ if(strchr(tmp, '.'))
+ *strchr(tmp, '.')= '\0';
+ if(strchr(tmp, ','))
+ *strchr(tmp, ',')= '\0';
+ int mhz;
+ if(sscanf(tmp, "%d", &mhz)==1)
+ MHz = mhz;
+ }
+ }
+ }
+ }
if(!MHz)
MHz = 1000; // default to 1Ghz...
return MHz;
}
-int getNCpu(); // defined in wrappedlibc.c
-const char* getCpuName(); // same
+static int nCPU = 0;
+static double bogoMips = 100.;
-void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
+void grabNCpu() {
+ nCPU = 1; // default number of CPU to 1
+ FILE *f = fopen("/proc/cpuinfo", "r");
+ size_t dummy;
+ if(f) {
+ nCPU = 0;
+ int bogo = 0;
+ size_t len = 500;
+ char* line = malloc(len);
+ while ((dummy = getline(&line, &len, f)) != -1) {
+ if(!strncmp(line, "processor\t", strlen("processor\t")))
+ ++nCPU;
+ if(!bogo && !strncmp(line, "BogoMIPS\t", strlen("BogoMIPS\t"))) {
+ // grab 1st BogoMIPS
+ float tmp;
+ if(sscanf(line, "BogoMIPS\t: %g", &tmp)==1) {
+ bogoMips = tmp;
+ bogo = 1;
+ }
+ }
+ }
+ free(line);
+ fclose(f);
+ if(!nCPU) nCPU=1;
+ }
+}
+int getNCpu()
+{
+ if(!nCPU)
+ grabNCpu();
+ if(box64_wine && nCPU>64)
+ return 64;
+ return nCPU;
+}
+
+double getBogoMips()
+{
+ if(!nCPU)
+ grabNCpu();
+ return bogoMips;
+}
+
+const char* getCpuName()
+{
+ static char name[200] = "Unknown CPU";
+ static int done = 0;
+ if(done)
+ return name;
+ done = 1;
+ FILE* f = popen("lscpu | grep \"Model name:\" | sed -r 's/Model name:\\s{1,}//g'", "r");
+ if(f) {
+ char tmp[200] = "";
+ ssize_t s = fread(tmp, 1, 200, f);
+ pclose(f);
+ if(s>0) {
+ // worked! (unless it's saying "lscpu: command not found" or something like that)
+ if(!strstr(tmp, "lscpu")) {
+ // trim ending
+ while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
+ tmp[strlen(tmp)-1] = 0;
+ // incase multiple cpu type are present, there will be multiple lines
+ while(strchr(tmp, '\n'))
+ *strchr(tmp,'\n') = ' ';
+ strncpy(name, tmp, 199);
+ }
+ return name;
+ }
+ }
+ // failled, try to get architecture at least
+ f = popen("lscpu | grep \"Architecture:\" | sed -r 's/Architecture:\\s{1,}//g'", "r");
+ if(f) {
+ char tmp[200] = "";
+ ssize_t s = fread(tmp, 1, 200, f);
+ pclose(f);
+ if(s>0) {
+ // worked!
+ // trim ending
+ while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
+ tmp[strlen(tmp)-1] = 0;
+ // incase multiple cpu type are present, there will be multiple lines
+ while(strchr(tmp, '\n'))
+ *strchr(tmp,'\n') = ' ';
+ snprintf(name, 199, "unknown %s cpu", tmp);
+ return name;
+ }
+ }
+ // Nope, bye
+ return name;
+}
+
+const char* getBoxCpuName()
{
- emu->regs[_AX].dword[1] = emu->regs[_DX].dword[1] = emu->regs[_CX].dword[1] = emu->regs[_BX].dword[1] = 0;
- int ncpu = getNCpu();
static char branding[3*4*4+1] = "";
static int done = 0;
if(!done) {
@@ -38,26 +152,37 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
const char* name = getCpuName();
if(strstr(name, "MHz") || strstr(name, "GHz")) {
// name already have the speed in it
- snprintf(branding, 3*4*4, "Box64 on %s", name);
+ snprintf(branding, sizeof(branding), "Box64 on %.*s", 39, name);
} else {
- int MHz = get_cpuMhz();
- if(MHz>15000) { // swiches to GHz display...
- snprintf(branding, 3*4*4, "Box64 on %s @%1.2f GHz", name, MHz/1000.);
+ unsigned int MHz = get_cpuMhz();
+ if(MHz>1500) { // swiches to GHz display...
+ snprintf(branding, sizeof(branding), "Box64 on %.*s @%1.2f GHz", 28, name, MHz/1000.);
} else {
- snprintf(branding, 3*4*4, "Box64 on %s @%04d MHz", name, MHz);
+ snprintf(branding, sizeof(branding), "Box64 on %.*s @%04d MHz", 28, name, MHz);
}
}
+ }
+ return branding;
+}
+
+void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
+{
+ emu->regs[_AX].dword[1] = emu->regs[_DX].dword[1] = emu->regs[_CX].dword[1] = emu->regs[_BX].dword[1] = 0;
+ int ncpu = getNCpu();
+ if(ncpu>255) ncpu = 255;
+ if(!ncpu) ncpu = 1;
+ static char branding[3*4*4+1] = "";
+ if(!branding[0]) {
+ strcpy(branding, getBoxCpuName());
while(strlen(branding)<3*4*4) {
- memmove(branding+1, branding, strlen(branding));
+ memmove(branding+1, branding, strlen(branding)+1);
branding[0] = ' ';
}
}
- if(ncpu>255) ncpu = 255;
- if(!ncpu) ncpu = 1;
switch(tmp32u) {
case 0x0:
// emulate a P4. TODO: Emulate a Core2?
- R_EAX = 0x0000000D;//0x80000004;
+ R_EAX = 0x0000000F;//0x80000004;
// return GenuineIntel
R_EBX = 0x756E6547;
R_EDX = 0x49656E69;
@@ -65,13 +190,14 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
break;
case 0x1:
R_EAX = 0x00000601; // family and all
- R_EBX = 0 | (8<<0x8) | (ncpu<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31)
- {
+ R_EBX = 0 | (8<<0x8) | (/*ncpu*/1<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31)
+ /*{
int cpu = sched_getcpu();
if(cpu<0) cpu=0;
R_EAX |= cpu<<24;
- }
+ }*/
R_EDX = 1 // fpu
+ | 1<<2 // debugging extension
| 1<<4 // rdtsc
| 1<<8 // cmpxchg8
| 1<<11 // sep (sysenter & sysexit)
@@ -81,6 +207,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
| 1<<24 // fxsr (fxsave, fxrestore)
| 1<<25 // SSE
| 1<<26 // SSE2
+ | 1<<28 // HT / Multi-core
;
R_ECX = 1<<0 // SSE3
| 1<<1 // PCLMULQDQ
@@ -88,6 +215,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
| 1<<12 // fma
| 1<<13 // cx16 (cmpxchg16)
| 1<<19 // SSE4_1
+ | 1<<20 // SSE4_2
| 1<<22 // MOVBE
| 1<<23 // POPCOUNT
| 1<<25 // aesni
@@ -146,10 +274,13 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
R_EDX = 0;
break;
case 0x7: // extended bits...
- if(R_ECX==1) {
- R_EAX = 0; // Bit 5 is avx512_bf16
- } else
- R_EAX = R_ECX = R_EBX = R_EDX = 0; // TODO
+ if(R_ECX==0) {
+ R_EAX = 0;
+ R_EBX = 0 |
+ 1<<3 | // BMI1
+ //1<<8 | //BMI2
+ 1<<29; // SHA extension
+ } else {R_EAX = R_ECX = R_EBX = R_EDX = 0;}
break;
case 0xB: // Extended Topology Enumeration Leaf
//TODO!
@@ -171,17 +302,41 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
R_EAX = R_ECX = R_EBX = R_EDX = 0;
}
break;
-
+ case 0xE: //?
+ R_EAX = 0;
+ break;
+ case 0xF: //L3 Cache
+ switch(R_ECX) {
+ case 0:
+ R_EAX = 0;
+ R_EBX = 0; // maximum range of RMID of physical processor
+ R_ECX = 0;
+ R_EDX = 0; // bit 1 support L3 RDT Cache monitoring
+ break;
+ case 1:
+ R_EAX = 0;
+ R_EBX = 0; // Conversion factor
+ R_EDX = 0; // bit 0 = occupency monitoring
+ break;
+ default: R_EAX = 0;
+ }
+ break;
+
case 0x80000000: // max extended
R_EAX = 0x80000005;
break;
case 0x80000001: //Extended Processor Signature and Feature Bits
R_EAX = 0; // reserved
R_EBX = 0; // reserved
- R_ECX = (1<<5) | (1<<8); // LZCNT | PREFETCHW
- R_EDX = 1 | (1<<29); // x87 FPU? bit 29 is 64bits available
- //AMD flags?
- //R_EDX = 1 | (1<<8) | (1<<11) | (1<<15) | (1<<23) | (1<<29); // fpu+cmov+cx8+syscall+mmx+lm (mmxext=22, 3dnow=31, 3dnowext=30)
+ R_ECX = (1<<0) | (1<<5) | (1<<8); // LAHF_LM | LZCNT | PREFETCHW
+ R_EDX = 1 // x87 FPU
+ | (1<<8) // cx8: cmpxchg8b opcode
+ | (1<<11) // syscall
+ | (1<<15) // cmov: FCMOV opcodes
+ | (1<<23) // mmx: MMX available
+ | (1<<24) // fxsave
+ | (1<<27) // rdtscp
+ | (1<<29); // long mode 64bits available
break;
case 0x80000002: // Brand part 1 (branding signature)
R_EAX = ((uint32_t*)branding)[0];
diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c
index e41980c..6b0f620 100644
--- a/src/tools/rcfile.c
+++ b/src/tools/rcfile.c
@@ -22,6 +22,9 @@
// default rcfile
static const char default_rcfile[] =
+"[bash]\n"
+"BOX64_LOG=0\n"
+"\n"
"[deadcells]\n"
"BOX64_PREFER_EMULATED=1\n"
"\n"
@@ -37,6 +40,7 @@ static const char default_rcfile[] =
"\n"
"[heroic]\n"
"BOX64_NOSANDBOX=1\n"
+"BOX64_INPROCESSGPU=1\n"
"BOX64_MALLOC_HACK=2\n"
"\n"
"[LotCG.x86_64]\n"
@@ -45,6 +49,9 @@ static const char default_rcfile[] =
"[pressure-vessel-wrap]\n"
"BOX64_NOGTK=1\n"
"\n"
+"[ShovelKnight]\n"
+"BOX64_SDL2_JGUID=1\n"
+"\n"
"[Soma.bin.x86_64]\n"
"BOX64_DYNAREC_FASTROUND=0\n"
"\n"
@@ -53,12 +60,16 @@ static const char default_rcfile[] =
"\n"
"[steamwebhelper]\n"
"BOX64_NOSANDBOX=1\n"
+"BOX64_INPROCESSGPU=1\n"
"BOX64_MALLOC_HACK=2\n"
"BOX64_LOG=0\n"
"BOX64_DYNAREC_BIGBLOCK=0\n"
"\n"
"[steam-runtime-check-requirements]\n"
"BOX64_EXIT=1\n"
+"\n"
+"[steam-runtime-launcher-service]\n"
+"BOX64_EXIT=1\n"
;
// list of all entries
@@ -80,6 +91,7 @@ ENTRYBOOL(BOX64_X11GLX, box64_x11glx) \
ENTRYDSTRING(BOX64_LIBGL, box64_libGL) \
ENTRYBOOL(BOX64_SSE_FLUSHTO0, box64_sse_flushto0) \
ENTRYBOOL(BOX64_X87_NO80BITS, box64_x87_no80bits) \
+ENTRYBOOL(BOX64_SYNC_ROUNDING, box64_sync_rounding) \
ENTRYSTRING_(BOX64_EMULATED_LIBS, emulated_libs) \
ENTRYBOOL(BOX64_ALLOWMISSINGLIBS, allow_missing_libs) \
ENTRYBOOL(BOX64_PREFER_WRAPPED, box64_prefer_wrapped) \
@@ -88,12 +100,16 @@ ENTRYBOOL(BOX64_CRASHHANDLER, box64_dummy_crashhandler) \
ENTRYBOOL(BOX64_NOPULSE, box64_nopulse) \
ENTRYBOOL(BOX64_NOGTK, box64_nogtk) \
ENTRYBOOL(BOX64_NOVULKAN, box64_novulkan) \
+ENTRYBOOL(BOX64_FUTEX_WAITV, box64_futex_waitv) \
ENTRYSTRING_(BOX64_BASH, bash) \
-ENTRYINT(BOX64_JITGDB, jit_gdb, 0, 2, 2) \
+ENTRYINT(BOX64_JITGDB, jit_gdb, 0, 3, 2) \
ENTRYBOOL(BOX64_NOSANDBOX, box64_nosandbox) \
+ENTRYBOOL(BOX64_INPROCESSGPU, box64_inprocessgpu) \
ENTRYBOOL(BOX64_EXIT, want_exit) \
ENTRYBOOL(BOX64_LIBCEF, box64_libcef) \
+ENTRYBOOL(BOX64_SDL2_JGUID, box64_sdl2_jguid) \
ENTRYINT(BOX64_MALLOC_HACK, box64_malloc_hack, 0, 2, 2) \
+ENTRYSTRING_(BOX64_ENV, new_env) \
#ifdef HAVE_TRACE
#define SUPER2() \
@@ -122,7 +138,7 @@ ENTRYINT(BOX64_DYNAREC_DUMP, box64_dynarec_dump, 0, 2, 2) \
ENTRYINT(BOX64_DYNAREC_LOG, box64_dynarec_log, 0, 3, 2) \
ENTRYINT(BOX64_DYNAREC_BIGBLOCK, box64_dynarec_bigblock, 0, 3, 2) \
ENTRYSTRING_(BOX64_DYNAREC_FORWARD, box64_dynarec_forward) \
-ENTRYINT(BOX64_DYNAREC_STRONGMEM, box64_dynarec_strongmem, 0, 2, 2) \
+ENTRYINT(BOX64_DYNAREC_STRONGMEM, box64_dynarec_strongmem, 0, 3, 2) \
ENTRYBOOL(BOX64_DYNAREC_X87DOUBLE, box64_dynarec_x87double) \
ENTRYBOOL(BOX64_DYNAREC_FASTNAN, box64_dynarec_fastnan) \
ENTRYBOOL(BOX64_DYNAREC_FASTROUND, box64_dynarec_fastround) \
@@ -130,8 +146,10 @@ ENTRYINT(BOX64_DYNAREC_SAFEFLAGS, box64_dynarec_safeflags, 0, 2, 2) \
ENTRYBOOL(BOX64_DYNAREC_CALLRET, box64_dynarec_callret) \
ENTRYBOOL(BOX64_DYNAREC_BLEEDING_EDGE, box64_dynarec_bleeding_edge) \
ENTRYBOOL(BOX64_DYNAREC_JVM, box64_dynarec_jvm) \
+ENTRYBOOL(BOX64_DYNAREC_TBB, box64_dynarec_tbb) \
ENTRYINT(BOX64_DYNAREC_HOTPAGE, box64_dynarec_hotpage, 0, 255, 8) \
ENTRYBOOL(BOX64_DYNAREC_FASTPAGE, box64_dynarec_fastpage) \
+ENTRYBOOL(BOX64_DYNAREC_ALIGNED_ATOMICS, box64_dynarec_aligned_atomics) \
ENTRYBOOL(BOX64_DYNAREC_WAIT, box64_dynarec_wait) \
ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec) \
ENTRYBOOL(BOX64_DYNAREC_TEST, box64_dynarec_test) \
@@ -152,8 +170,10 @@ IGNORE(BOX64_DYNAREC_SAFEFLAGS) \
IGNORE(BOX64_DYNAREC_CALLRET) \
IGNORE(BOX64_DYNAREC_BLEEDING_EDGE) \
IGNORE(BOX64_DYNAREC_JVM) \
+IGNORE(BOX64_DYNAREC_TBB) \
IGNORE(BOX64_DYNAREC_HOTPAGE) \
IGNORE(BOX64_DYNAREC_FASTPAGE) \
+IGNORE(BOX64_DYNAREC_ALIGNED_ATOMICS) \
IGNORE(BOX64_DYNAREC_WAIT) \
IGNORE(BOX64_NODYNAREC) \
IGNORE(BOX64_DYNAREC_TEST) \
@@ -277,6 +297,15 @@ static void trimString(char* s)
memmove(s, s+1, strlen(s));
}
+#ifdef ANDROID
+static int shm_open(const char *name, int oflag, mode_t mode) {
+ return -1;
+}
+static int shm_unlink(const char *name) {
+ return -1;
+}
+#endif
+
void LoadRCFile(const char* filename)
{
FILE *f = NULL;
@@ -425,6 +454,7 @@ extern int ftrace_has_pid;
extern FILE* ftrace;
extern char* ftrace_name;
void openFTrace(const char* newtrace);
+void addNewEnvVar(const char* s);
#ifdef DYNAREC
void GatherDynarecExtensions();
#endif
@@ -489,6 +519,7 @@ void ApplyParams(const char* name)
if(param->is_box64_path_present) AppendList(&my_context->box64_path, param->box64_path, 1);
if(param->is_trace_file_present) {
// open a new ftrace...
+ printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_TRACE_FILE", param->trace_file);
if(ftrace_name) {
fclose(ftrace);
}
@@ -498,6 +529,10 @@ void ApplyParams(const char* name)
AppendList(&my_context->box64_emulated_libs, param->emulated_libs, 0);
printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_EMULATED_LIBS", param->emulated_libs);
}
+ if(param->is_new_env_present) {
+ addNewEnvVar(param->new_env);
+ printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV", param->new_env);
+ }
if(param->is_bash_present && FileIsX64ELF(param->bash)) {
if(my_context->bashpath)
free(my_context->bashpath);
@@ -512,7 +547,7 @@ void ApplyParams(const char* name)
my_context->x64trace = 1;
box64_trace = p;
}
- printf_log(LOG_INFO, "Applying %s=%s", "BOX64_TRACE", param->trace);
+ printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_TRACE", param->trace);
}
if(param->is_trace_init_present) {
char* p = param->trace_init;
@@ -520,7 +555,7 @@ void ApplyParams(const char* name)
my_context->x64trace = 1;
trace_init = p;
}
- printf_log(LOG_INFO, "Applying %s=%s", "BOX64_TRACE_INIT", param->trace_init);
+ printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_TRACE_INIT", param->trace_init);
}
if(my_context->x64trace && !old_x64trace) {
printf_log(LOG_INFO, "Initializing Zydis lib\n");
@@ -559,9 +594,14 @@ void ApplyParams(const char* name)
}
if(!olddynarec && box64_dynarec)
GatherDynarecExtensions();
+ if(param->is_box64_dynarec_test_present && box64_dynarec_test) {
+ box64_dynarec_fastnan = 0;
+ box64_dynarec_fastround = 0;
+ box64_dynarec_callret = 0;
+ }
#endif
if(box64_log==3) {
box64_log = 2;
box64_dump = 1;
}
-} \ No newline at end of file
+}
diff --git a/src/tools/wine_tools.c b/src/tools/wine_tools.c
index 199a0fc..e13b373 100644
--- a/src/tools/wine_tools.c
+++ b/src/tools/wine_tools.c
@@ -8,6 +8,7 @@
#include "wine_tools.h"
#include "debug.h"
#include "box64context.h"
+#include "custommem.h"
typedef struct wine_prereserve_s
{
@@ -76,6 +77,7 @@ void wine_prereserve(const char* reserve)
my_wine_reserve[idx].addr = NULL;
my_wine_reserve[idx].size = 0;
} else {
+ setProtection_mmap((uintptr_t)my_wine_reserve[idx].addr, my_wine_reserve[idx].size, 0);
printf_log(LOG_DEBUG, "WINE prereserve of %p:0x%lx done\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size);
++idx;
}
diff --git a/src/wrapped/wrappedandroidshmem.c b/src/wrapped/wrappedandroidshmem.c
new file mode 100755
index 0000000..ac4c874
--- /dev/null
+++ b/src/wrapped/wrappedandroidshmem.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* androidshmemName = "libandroid-shmem.so";
+#define LIBNAME androidshmem
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedandroidshmem_private.h b/src/wrapped/wrappedandroidshmem_private.h
new file mode 100755
index 0000000..84f29a8
--- /dev/null
+++ b/src/wrapped/wrappedandroidshmem_private.h
@@ -0,0 +1,8 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+GO(shmctl, iFiip)
+GO(shmget, iFiLi)
+GO(shmat, pFipi)
+GO(shmdt, iFp)
diff --git a/src/wrapped/wrappedandroidsupport.c b/src/wrapped/wrappedandroidsupport.c
new file mode 100644
index 0000000..909552f
--- /dev/null
+++ b/src/wrapped/wrappedandroidsupport.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* androidsupportName = "libandroid-support.so";
+
+#define LIBNAME androidsupport
+
+#define CUSTOM_INIT \
+ setNeededLibs(lib, 1, "libc.so");
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedandroidsupport_private.h b/src/wrapped/wrappedandroidsupport_private.h
new file mode 100644
index 0000000..a0ed8e1
--- /dev/null
+++ b/src/wrapped/wrappedandroidsupport_private.h
@@ -0,0 +1,4 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA) && defined(GOS))
+#error Meh...
+#endif
+
diff --git a/src/wrapped/wrappedatomic_private.h b/src/wrapped/wrappedatomic_private.h
index f98dea6..9566807 100644
--- a/src/wrapped/wrappedatomic_private.h
+++ b/src/wrapped/wrappedatomic_private.h
@@ -12,13 +12,13 @@
//GO(__atomic_and_fetch_2,
//GO(__atomic_and_fetch_4,
//GO(__atomic_and_fetch_8,
-GO(__atomic_compare_exchange, iFpii)
+GO(__atomic_compare_exchange, iFLpppii)
//GO(__atomic_compare_exchange_1,
//GO(__atomic_compare_exchange_16,
//GO(__atomic_compare_exchange_2,
//GO(__atomic_compare_exchange_4,
//GO(__atomic_compare_exchange_8,
-GO(__atomic_exchange, vFpppi)
+GO(__atomic_exchange, vFLpppi)
//GO(__atomic_exchange_1,
//GO(__atomic_exchange_16,
//GO(__atomic_exchange_2,
@@ -60,7 +60,7 @@ GO(__atomic_exchange, vFpppi)
//GO(atomic_flag_test_and_set,
//GO(atomic_flag_test_and_set_explicit,
GO(__atomic_is_lock_free, iFLp)
-GO(__atomic_load, vFppi)
+GO(__atomic_load, vFLppi)
//GO(__atomic_load_1,
//GO(__atomic_load_16,
//GO(__atomic_load_2,
@@ -77,7 +77,7 @@ GO(__atomic_load, vFppi)
//GO(__atomic_or_fetch_4,
//GO(__atomic_or_fetch_8,
//GO(atomic_signal_fence,
-GO(__atomic_store, vFppi)
+GO(__atomic_store, vFLppi)
//GO(__atomic_store_1,
//GO(__atomic_store_16,
//GO(__atomic_store_2,
diff --git a/src/wrapped/wrappedayatanaappindicator3.c b/src/wrapped/wrappedayatanaappindicator3.c
new file mode 100644
index 0000000..8297733
--- /dev/null
+++ b/src/wrapped/wrappedayatanaappindicator3.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* ayatanaappindicator3Name = "libayatana-appindicator3.so.1";
+
+#define LIBNAME ayatanaappindicator3
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedayatanaappindicator3_private.h b/src/wrapped/wrappedayatanaappindicator3_private.h
new file mode 100644
index 0000000..8c76408
--- /dev/null
+++ b/src/wrapped/wrappedayatanaappindicator3_private.h
@@ -0,0 +1,45 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+GO(app_indicator_build_menu_from_desktop, vFppp)
+GO(app_indicator_category_get_type, pFv)
+GO(app_indicator_get_attention_icon, pFp)
+GO(app_indicator_get_attention_icon_desc, pFp)
+GO(app_indicator_get_category, iFp)
+GO(app_indicator_get_icon, pFp)
+GO(app_indicator_get_icon_desc, pFp)
+GO(app_indicator_get_icon_theme_path, pFp)
+GO(app_indicator_get_id, pFp)
+GO(app_indicator_get_label, pFp)
+GO(app_indicator_get_label_guide, pFp)
+GO(app_indicator_get_menu, pFp)
+GO(app_indicator_get_ordering_index, uFp)
+GO(app_indicator_get_secondary_activate_target, pFp)
+GO(app_indicator_get_status, iFp)
+GO(app_indicator_get_title, pFp)
+GO(app_indicator_get_type, iFv)
+GO(app_indicator_new, pFppi)
+GO(app_indicator_new_with_path, pFppip)
+GO(app_indicator_set_attention_icon, vFpp)
+GO(app_indicator_set_attention_icon_full, vFppp)
+GO(app_indicator_set_icon, vFpp)
+GO(app_indicator_set_icon_full, vFppp)
+GO(app_indicator_set_icon_theme_path, vFpp)
+GO(app_indicator_set_label, vFppp)
+GO(app_indicator_set_menu, vFpp)
+GO(app_indicator_set_ordering_index, vFpu)
+GO(app_indicator_set_secondary_activate_target, vFpp)
+GO(app_indicator_set_status, vFpi)
+GO(app_indicator_set_title, vFpp)
+GO(app_indicator_status_get_type, iFv)
+//GO(_application_service_marshal_VOID__BOOLEAN_STRING_OBJECT,
+//GO(_application_service_marshal_VOID__INT_INT,
+//GO(_application_service_marshal_VOID__INT_STRING,
+//GO(_application_service_marshal_VOID__INT_STRING_STRING,
+//GO(_application_service_marshal_VOID__INT_UINT,
+//GO(_application_service_marshal_VOID__STRING_INT_STRING_STRING_STRING_STRING_STRING,
+//GO(_application_service_marshal_VOID__STRING_STRING,
+//GO(_generate_id,
+//DATA(_notification_item,
+//DATA(_notification_watcher,
diff --git a/src/wrapped/wrappedcurl.c b/src/wrapped/wrappedcurl.c
index 490d7f8..b7d588c 100644
--- a/src/wrapped/wrappedcurl.c
+++ b/src/wrapped/wrappedcurl.c
@@ -16,7 +16,12 @@
#include "emu/x64emu_private.h"
#include "callback.h"
-const char* curlName = "libcurl.so.4";
+#ifdef ANDROID
+ const char* curlName = "libcurl.so";
+#else
+ const char* curlName = "libcurl.so.4";
+#endif
+
#define ALTNAME "libcurl-gnutls.so.4"
#define LIBNAME curl
diff --git a/src/wrapped/wrappedcurl_private.h b/src/wrapped/wrappedcurl_private.h
index ffcc105..7712cd1 100644
--- a/src/wrapped/wrappedcurl_private.h
+++ b/src/wrapped/wrappedcurl_private.h
@@ -50,6 +50,7 @@ GO(curl_multi_fdset, uFppppp)
GO(curl_multi_info_read, pFpp)
GO(curl_multi_init, pFv)
GO(curl_multi_perform, uFpp)
+GO(curl_multi_poll, iFppuip) // since 7.66.0
GO(curl_multi_remove_handle, uFpp)
GOM(curl_multi_setopt, iFEpup)
//GO(curl_multi_socket,
diff --git a/src/wrapped/wrappeddbusmenuglib.c b/src/wrapped/wrappeddbusmenuglib.c
new file mode 100644
index 0000000..dd5f318
--- /dev/null
+++ b/src/wrapped/wrappeddbusmenuglib.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+
+#ifdef ANDROID
+ const char* dbusmenuglibName = "libdbusmenu-glib.so";
+#else
+ const char* dbusmenuglibName = "libdbusmenu-glib.so.4";
+#endif
+
+#define LIBNAME dbusmenuglib
+
+#include "generated/wrappeddbusmenuglibtypes.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3)
+
+// DbusmenuClientTypeHandler
+#define GO(A) \
+static uintptr_t my_DbusmenuClientTypeHandler_fct_##A = 0; \
+static int my_DbusmenuClientTypeHandler_##A(void* a, void* b, void* c, void* d) \
+{ \
+ return RunFunctionFmt(my_DbusmenuClientTypeHandler_fct_##A, "pppp", a, b, c, d);\
+}
+SUPER()
+#undef GO
+static void* findDbusmenuClientTypeHandlerFct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_DbusmenuClientTypeHandler_fct_##A == (uintptr_t)fct) return my_DbusmenuClientTypeHandler_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_DbusmenuClientTypeHandler_fct_##A == 0) {my_DbusmenuClientTypeHandler_fct_##A = (uintptr_t)fct; return my_DbusmenuClientTypeHandler_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for dbusmenuglib DbusmenuClientTypeHandler callback\n");
+ return NULL;
+}
+
+// DbusmenuMenuitem
+#define GO(A) \
+static uintptr_t my_DbusmenuMenuitem_fct_##A = 0; \
+static void my_DbusmenuMenuitem_##A(void* a, void* b) \
+{ \
+ RunFunctionFmt(my_DbusmenuMenuitem_fct_##A, "pp", a, b);\
+}
+SUPER()
+#undef GO
+static void* findDbusmenuMenuitemFct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_DbusmenuMenuitem_fct_##A == (uintptr_t)fct) return my_DbusmenuMenuitem_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_DbusmenuMenuitem_fct_##A == 0) {my_DbusmenuMenuitem_fct_##A = (uintptr_t)fct; return my_DbusmenuMenuitem_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for dbusmenuglib DbusmenuMenuitem callback\n");
+ return NULL;
+}
+
+#undef SUPER
+
+EXPORT int my_dbusmenu_client_add_type_handler(x64emu_t* emu, void* client, void* type, void* f)
+{
+ (void)emu;
+ return my->dbusmenu_client_add_type_handler(client, type, findDbusmenuClientTypeHandlerFct(f));
+}
+
+EXPORT void my_dbusmenu_menuitem_foreach(x64emu_t* emu, void* mi, void* f, void* data)
+{
+ (void)emu;
+ my->dbusmenu_menuitem_foreach(mi, findDbusmenuMenuitemFct(f), data);
+}
+
+EXPORT void my_dbusmenu_menuitem_send_about_to_show(x64emu_t* emu, void* mi, void* f, void* data)
+{
+ (void)emu;
+ my->dbusmenu_menuitem_send_about_to_show(mi, findDbusmenuMenuitemFct(f), data);
+}
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#define CUSTOM_INIT \
+ getMy(lib); \
+
+#define CUSTOM_FINI \
+ freeMy();
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappeddbusmenuglib_private.h b/src/wrapped/wrappeddbusmenuglib_private.h
new file mode 100644
index 0000000..c749144
--- /dev/null
+++ b/src/wrapped/wrappeddbusmenuglib_private.h
@@ -0,0 +1,84 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+//DATA(dbus_menu_clean_xml,
+GOM(dbusmenu_client_add_type_handler, iFEppp)
+//GO(dbusmenu_client_add_type_handler_full,
+GO(dbusmenu_client_get_icon_paths, pFp)
+GO(dbusmenu_client_get_root, pFp)
+//GO(dbusmenu_client_get_status,
+//GO(dbusmenu_client_get_text_direction,
+GO(dbusmenu_client_get_type, pFv)
+//GO(dbusmenu_client_menuitem_get_type,
+//GO(dbusmenu_client_menuitem_new,
+//GO(dbusmenu_client_new,
+//GO(dbusmenu_client_send_about_to_show,
+//GO(dbusmenu_client_send_event,
+//GO(dbusmenu_defaults_default_get,
+//GO(dbusmenu_defaults_default_get_type,
+//GO(dbusmenu_defaults_default_set,
+//GO(dbusmenu_defaults_get_type,
+//GO(dbusmenu_defaults_ref_default,
+//GO(dbusmenu_menuitem_build_variant,
+GO(dbusmenu_menuitem_child_add_position, iFppu)
+GO(dbusmenu_menuitem_child_append, iFpp)
+GO(dbusmenu_menuitem_child_delete, iFpp)
+GO(dbusmenu_menuitem_child_find, pFpi)
+GO(dbusmenu_menuitem_child_prepend, iFpp)
+GO(dbusmenu_menuitem_child_reorder, iFppu)
+//GO(dbusmenu_menuitem_exposed,
+GO(dbusmenu_menuitem_find_id, pFpi)
+GOM(dbusmenu_menuitem_foreach, vFEppp)
+GO(dbusmenu_menuitem_get_children, pFp)
+GO(dbusmenu_menuitem_get_id, iFp)
+GO(dbusmenu_menuitem_get_parent, pFp)
+GO(dbusmenu_menuitem_get_position, uFpp)
+GO(dbusmenu_menuitem_get_position_realized, uFpp)
+GO(dbusmenu_menuitem_get_root, iFp)
+GO(dbusmenu_menuitem_get_type, iFv)
+GO(dbusmenu_menuitem_handle_event, vFpppu)
+GO(dbusmenu_menuitem_new, pFv)
+GO(dbusmenu_menuitem_new_with_id, pFi)
+GO(dbusmenu_menuitem_properties_copy, pFp)
+GO(dbusmenu_menuitem_properties_list, pFp)
+//GO(dbusmenu_menuitem_properties_variant,
+GO(dbusmenu_menuitem_property_exist, iFpp)
+GO(dbusmenu_menuitem_property_get, pFpp)
+GO(dbusmenu_menuitem_property_get_bool, iFpp)
+GO(dbusmenu_menuitem_property_get_byte_array, pFppp)
+GO(dbusmenu_menuitem_property_get_int, iFpp)
+GO(dbusmenu_menuitem_property_get_variant, pFpp)
+//GO(dbusmenu_menuitem_property_is_default,
+GO(dbusmenu_menuitem_property_remove, vFpp)
+GO(dbusmenu_menuitem_property_set, iFppp)
+GO(dbusmenu_menuitem_property_set_bool, iFppi)
+GO(dbusmenu_menuitem_property_set_byte_array, iFpppL)
+GO(dbusmenu_menuitem_property_set_int, iFppi)
+GO(dbusmenu_menuitem_property_set_variant, iFppp)
+GO(dbusmenu_menuitem_proxy_get_type, iFv)
+//GO(dbusmenu_menuitem_proxy_get_wrapped,
+//GO(dbusmenu_menuitem_proxy_new,
+//GO(dbusmenu_menuitem_realized,
+GOM(dbusmenu_menuitem_send_about_to_show, vFEppp)
+//GO(dbusmenu_menuitem_set_parent,
+//GO(dbusmenu_menuitem_set_realized,
+GO(dbusmenu_menuitem_set_root, vFpi)
+GO(dbusmenu_menuitem_show_to_user, vFpu)
+GO(dbusmenu_menuitem_take_children, pFp)
+//GO(dbusmenu_menuitem_unparent,
+GO(dbusmenu_server_get_icon_paths, pFp)
+GO(dbusmenu_server_get_status, iFp)
+GO(dbusmenu_server_get_text_direction, iFp)
+GO(dbusmenu_server_get_type, iFv)
+GO(dbusmenu_server_new, pFp)
+GO(dbusmenu_server_set_icon_paths, vFpp)
+GO(dbusmenu_server_set_root, vFpp)
+GO(dbusmenu_server_set_status, vFpi)
+GO(dbusmenu_server_set_text_direction, vFpi)
+//GO(dbusmenu_status_get_nick,
+GO(dbusmenu_status_get_type, iFv)
+//GO(dbusmenu_status_get_value_from_nick,
+//GO(dbusmenu_text_direction_get_nick,
+//GO(dbusmenu_text_direction_get_type,
+//GO(dbusmenu_text_direction_get_value_from_nick,
diff --git a/src/wrapped/wrappedevent21.c b/src/wrapped/wrappedevent21.c
new file mode 100644
index 0000000..1cf4fe3
--- /dev/null
+++ b/src/wrapped/wrappedevent21.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+
+const char* event21Name = "libevent-2.1.so.7";
+#define LIBNAME event21
+
+#include "generated/wrappedevent21types.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+ GO(0) \
+ GO(1) \
+ GO(2) \
+ GO(3)
+
+// event_set
+#define GO(A) \
+static uintptr_t my_event_set_fct_##A = 0; \
+static void my_event_set_##A(int a, short b, void* c) \
+{ \
+ RunFunctionFmt(my_event_set_fct_##A, "iwp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findevent_setFct(void* fct)
+{
+ if(!fct) return NULL;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_event_set_fct_##A == (uintptr_t)fct) return my_event_set_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_event_set_fct_##A == 0) {my_event_set_fct_##A = (uintptr_t)fct; return my_event_set_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for libevent-2.1 event_set callback\n");
+ return NULL;
+}
+
+#undef SUPER
+
+EXPORT void my_event_set(x64emu_t* emu, void* evt, int sock, short i, void* f, void* data)
+{
+ my->event_set(evt, sock, i, findevent_setFct(f), data);
+}
+
+#define CUSTOM_INIT \
+ getMy(lib);
+
+#define CUSTOM_FINI \
+ freeMy();
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedevent21_private.h b/src/wrapped/wrappedevent21_private.h
new file mode 100644
index 0000000..727916f
--- /dev/null
+++ b/src/wrapped/wrappedevent21_private.h
@@ -0,0 +1,646 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+//GO(bufferevent_add_event_,
+//GO(bufferevent_add_to_rate_limit_group,
+//GO(bufferevent_base_set,
+//GO(bufferevent_decref,
+//GO(bufferevent_decref_and_unlock_,
+//GO(bufferevent_decrement_read_buckets_,
+//GO(bufferevent_decrement_read_limit,
+//GO(bufferevent_decrement_write_buckets_,
+//GO(bufferevent_decrement_write_limit,
+//GO(bufferevent_disable,
+//GO(bufferevent_disable_hard_,
+//GO(bufferevent_enable,
+//GO(bufferevent_enable_locking_,
+//GO(bufferevent_filter_new,
+//GO(bufferevent_flush,
+//GO(bufferevent_free,
+//GO(bufferevent_generic_adj_existing_timeouts_,
+//GO(bufferevent_generic_adj_timeouts_,
+//GO(bufferevent_get_base,
+//GO(bufferevent_getcb,
+//GO(bufferevent_get_enabled,
+//GO(bufferevent_getfd,
+//GO(bufferevent_get_input,
+//GO(bufferevent_get_max_single_read,
+//GO(bufferevent_get_max_single_write,
+//GO(bufferevent_get_max_to_read,
+//GO(bufferevent_get_max_to_write,
+//GO(bufferevent_get_options_,
+//GO(bufferevent_get_output,
+//GO(bufferevent_get_priority,
+//GO(bufferevent_get_read_limit,
+//GO(bufferevent_get_read_max_,
+//GO(bufferevent_get_token_bucket_cfg,
+//GO(bufferevent_get_underlying,
+//GO(bufferevent_getwatermark,
+//GO(bufferevent_get_write_limit,
+//GO(bufferevent_get_write_max_,
+//GO(bufferevent_incref,
+//GO(bufferevent_incref_and_lock_,
+//GO(bufferevent_init_common_,
+//GO(bufferevent_init_generic_timeout_cbs_,
+//GO(bufferevent_lock,
+//GO(bufferevent_new,
+//DATA(bufferevent_ops_filter,
+//DATA(bufferevent_ops_pair,
+//DATA(bufferevent_ops_socket,
+//GO(bufferevent_pair_get_partner,
+//GO(bufferevent_pair_new,
+//GO(bufferevent_priority_set,
+//GO(bufferevent_ratelim_init_,
+//GO(bufferevent_rate_limit_group_decrement_read,
+//GO(bufferevent_rate_limit_group_decrement_write,
+//GO(bufferevent_rate_limit_group_free,
+//GO(bufferevent_rate_limit_group_get_read_limit,
+//GO(bufferevent_rate_limit_group_get_totals,
+//GO(bufferevent_rate_limit_group_get_write_limit,
+//GO(bufferevent_rate_limit_group_new,
+//GO(bufferevent_rate_limit_group_reset_totals,
+//GO(bufferevent_rate_limit_group_set_cfg,
+//GO(bufferevent_rate_limit_group_set_min_share,
+//GO(bufferevent_read,
+//GO(bufferevent_read_buffer,
+//GO(bufferevent_remove_from_rate_limit_group,
+//GO(bufferevent_remove_from_rate_limit_group_internal_,
+//GO(bufferevent_run_eventcb_,
+//GO(bufferevent_run_readcb_,
+//GO(bufferevent_run_writecb_,
+//GO(bufferevent_setcb,
+//GO(bufferevent_setfd,
+//GO(bufferevent_set_max_single_read,
+//GO(bufferevent_set_max_single_write,
+//GO(bufferevent_set_rate_limit,
+//GO(bufferevent_settimeout,
+//GO(bufferevent_set_timeouts,
+//GO(bufferevent_setwatermark,
+//GO(bufferevent_socket_connect,
+//GO(bufferevent_socket_connect_hostname,
+//GO(bufferevent_socket_get_conn_address_,
+//GO(bufferevent_socket_get_dns_error,
+//GO(bufferevent_socket_new,
+//GO(bufferevent_socket_set_conn_address_,
+//GO(bufferevent_socket_set_conn_address_fd_,
+//GO(bufferevent_suspend_read_,
+//GO(bufferevent_suspend_write_,
+//GO(bufferevent_trigger,
+//GO(bufferevent_trigger_event,
+//GO(bufferevent_unlock,
+//GO(bufferevent_unsuspend_read_,
+//GO(bufferevent_unsuspend_write_,
+//GO(bufferevent_write,
+//GO(bufferevent_write_buffer,
+//DATA(epollops,
+//GO(evbuffer_add,
+//GO(evbuffer_add_buffer,
+//GO(evbuffer_add_buffer_reference,
+//GO(evbuffer_add_cb,
+//GO(evbuffer_add_file,
+//GO(evbuffer_add_file_segment,
+//GO(evbuffer_add_iovec,
+//GO(evbuffer_add_printf,
+//GO(evbuffer_add_reference,
+//GO(evbuffer_add_vprintf,
+//GO(evbuffer_cb_clear_flags,
+//GO(evbuffer_cb_set_flags,
+//GO(evbuffer_chain_pin_,
+//GO(evbuffer_chain_unpin_,
+//GO(evbuffer_clear_flags,
+//GO(evbuffer_commit_space,
+//GO(evbuffer_copyout,
+//GO(evbuffer_copyout_from,
+//GO(evbuffer_decref_and_unlock_,
+//GO(evbuffer_defer_callbacks,
+//GO(evbuffer_drain,
+//GO(evbuffer_enable_locking,
+//GO(evbuffer_expand,
+//GO(evbuffer_expand_fast_,
+//GO(evbuffer_file_segment_add_cleanup_cb,
+//GO(evbuffer_file_segment_free,
+//GO(evbuffer_file_segment_new,
+//GO(evbuffer_find,
+//GO(evbuffer_free,
+//GO(evbuffer_freeze,
+//GO(evbuffer_get_callbacks_,
+//GO(evbuffer_get_contiguous_space,
+//GO(evbuffer_get_length,
+//GO(evbuffer_incref_,
+//GO(evbuffer_incref_and_lock_,
+//GO(evbuffer_invoke_callbacks_,
+//GO(evbuffer_lock,
+//GO(evbuffer_new,
+//GO(evbuffer_peek,
+//GO(evbuffer_prepend,
+//GO(evbuffer_prepend_buffer,
+//GO(evbuffer_ptr_set,
+//GO(evbuffer_pullup,
+//GO(evbuffer_read,
+//GO(evbuffer_readline,
+//GO(evbuffer_readln,
+//GO(evbuffer_read_setup_vecs_,
+//GO(evbuffer_remove,
+//GO(evbuffer_remove_buffer,
+//GO(evbuffer_remove_cb,
+//GO(evbuffer_remove_cb_entry,
+//GO(evbuffer_reserve_space,
+//GO(evbuffer_search,
+//GO(evbuffer_search_eol,
+//GO(evbuffer_search_range,
+//GO(evbuffer_setcb,
+//GO(evbuffer_set_flags,
+//GO(evbuffer_set_parent_,
+//GO(evbuffer_unfreeze,
+//GO(evbuffer_unlock,
+//GO(evbuffer_write,
+//GO(evbuffer_write_atmost,
+//GO(evconnlistener_disable,
+//GO(evconnlistener_enable,
+//GO(evconnlistener_free,
+//GO(evconnlistener_get_base,
+//GO(evconnlistener_get_fd,
+//GO(evconnlistener_new,
+//GO(evconnlistener_new_bind,
+//GO(evconnlistener_set_cb,
+//GO(evconnlistener_set_error_cb,
+//GO(evdns_add_server_port,
+//GO(evdns_add_server_port_with_base,
+//GO(evdns_base_clear_host_addresses,
+//GO(evdns_base_clear_nameservers_and_suspend,
+//GO(evdns_base_count_nameservers,
+//GO(evdns_base_free,
+//GO(evdns_base_get_nameserver_addr,
+//GO(evdns_base_load_hosts,
+//GO(evdns_base_nameserver_add,
+//GO(evdns_base_nameserver_ip_add,
+//GO(evdns_base_nameserver_sockaddr_add,
+//GO(evdns_base_new,
+//GO(evdns_base_resolv_conf_parse,
+//GO(evdns_base_resolve_ipv4,
+//GO(evdns_base_resolve_ipv6,
+//GO(evdns_base_resolve_reverse,
+//GO(evdns_base_resolve_reverse_ipv6,
+//GO(evdns_base_resume,
+//GO(evdns_base_search_add,
+//GO(evdns_base_search_clear,
+//GO(evdns_base_search_ndots_set,
+//GO(evdns_base_set_option,
+//GO(evdns_cancel_request,
+//GO(evdns_clear_nameservers_and_suspend,
+//GO(evdns_close_server_port,
+//GO(evdns_count_nameservers,
+//GO(evdns_err_to_string,
+//GO(evdns_getaddrinfo,
+//GO(evdns_getaddrinfo_cancel,
+//GO(evdns_get_global_base,
+//GO(evdns_init,
+//GO(evdns_nameserver_add,
+//GO(evdns_nameserver_ip_add,
+//GO(evdns_resolv_conf_parse,
+//GO(evdns_resolve_ipv4,
+//GO(evdns_resolve_ipv6,
+//GO(evdns_resolve_reverse,
+//GO(evdns_resolve_reverse_ipv6,
+//GO(evdns_resume,
+//GO(evdns_search_add,
+//GO(evdns_search_clear,
+//GO(evdns_search_ndots_set,
+//GO(evdns_server_request_add_aaaa_reply,
+//GO(evdns_server_request_add_a_reply,
+//GO(evdns_server_request_add_cname_reply,
+//GO(evdns_server_request_add_ptr_reply,
+//GO(evdns_server_request_add_reply,
+//GO(evdns_server_request_drop,
+//GO(evdns_server_request_get_requesting_addr,
+//GO(evdns_server_request_respond,
+//GO(evdns_server_request_set_flags,
+//GO(evdns_set_log_fn,
+//GO(evdns_set_option,
+//GO(evdns_set_random_bytes_fn,
+//GO(evdns_set_transaction_id_fn,
+//GO(evdns_shutdown,
+//GO(event_active,
+//GO(event_active_later_,
+//GO(event_active_later_nolock_,
+//GO(event_active_nolock_,
+GO(event_add, iFpp)
+//GO(event_add_nolock_,
+//GO(event_assign,
+//GO(event_base_active_by_fd,
+//GO(event_base_active_by_signal,
+//GO(event_base_add_virtual_,
+//GO(event_base_assert_ok_,
+//GO(event_base_assert_ok_nolock_,
+//GO(event_base_del_virtual_,
+//GO(event_base_dispatch,
+//GO(event_base_dump_events,
+//GO(event_base_foreach_event,
+//GO(event_base_foreach_event_nolock_,
+GO(event_base_free, vFp)
+//GO(event_base_free_nofinalize,
+//GO(event_base_get_features,
+//GO(event_base_get_max_events,
+//GO(event_base_get_method,
+//GO(event_base_get_npriorities,
+//GO(event_base_get_num_events,
+//GO(event_base_get_running_event,
+//GO(event_base_gettimeofday_cached,
+//GO(event_base_got_break,
+//GO(event_base_got_exit,
+//GO(event_base_init_common_timeout,
+GO(event_base_loop, iFpi)
+GO(event_base_loopbreak, iFp)
+//GO(event_base_loopcontinue,
+//GO(event_base_loopexit,
+GO(event_base_new, pFv)
+//GO(event_base_new_with_config,
+//GO(event_base_once,
+//GO(event_base_priority_init,
+GO(event_base_set, iFpp)
+//GO(event_base_start_iocp_,
+//GO(event_base_stop_iocp_,
+//GO(event_base_update_cache_time,
+//GO(event_callback_activate_,
+//GO(event_callback_activate_later_nolock_,
+//GO(event_callback_activate_nolock_,
+//GO(event_callback_cancel_,
+//GO(event_callback_cancel_nolock_,
+//GO(event_callback_finalize_,
+//GO(event_callback_finalize_many_,
+//GO(event_callback_finalize_nolock_,
+//GO(event_callback_init_,
+//GO(event_changelist_add_,
+//GO(event_changelist_del_,
+//GO(event_changelist_freemem_,
+//GO(event_changelist_init_,
+//GO(event_changelist_remove_all_,
+//GO(event_config_avoid_method,
+//GO(event_config_free,
+//GO(event_config_new,
+//GO(event_config_require_features,
+//GO(event_config_set_flag,
+//GO(event_config_set_max_dispatch_interval,
+//GO(event_config_set_num_cpus_hint,
+//DATAB(event_debug_created_threadable_ctx_,
+//DATAB(event_debug_logging_mask_,
+//GO(event_debug_map_HT_CLEAR,
+//GO(event_debug_map_HT_GROW,
+//GO(event_debug_map_HT_REP_IS_BAD_,
+//DATAB(event_debug_mode_on_,
+//GO(event_debug_unassign,
+//GO(event_debugx_,
+//GO(event_deferred_cb_cancel_,
+//GO(event_deferred_cb_init_,
+//GO(event_deferred_cb_schedule_,
+//GO(event_deferred_cb_set_priority_,
+GO(event_del, iFp)
+//GO(event_del_block,
+//GO(event_del_noblock,
+//GO(event_del_nolock_,
+//GO(event_disable_debug_mode,
+//GO(event_dispatch,
+//GO(event_enable_debug_logging,
+//GO(event_enable_debug_mode,
+//GO(event_err,
+//GO(event_errx,
+//GO(event_finalize,
+//GO(event_free,
+//GO(event_free_finalize,
+//GO(event_get_assignment,
+//GO(event_get_base,
+//GO(event_get_callback,
+//GO(event_get_callback_arg,
+//GO(event_get_events,
+GO(event_get_fd, iFp)
+//GO(event_get_method,
+//GO(event_get_priority,
+//GO(event_get_struct_event_size,
+//GO(event_get_supported_methods,
+//GO(event_gettime_monotonic,
+//GO(event_get_version,
+//GO(event_get_version_number,
+//DATAB(event_global_current_base_,
+//GO(event_global_setup_locks_,
+//GO(event_init,
+//GO(event_initialized,
+//GO(event_logv_,
+//GO(event_loop,
+//GO(event_loopbreak,
+//GO(event_loopexit,
+//GO(event_mm_calloc_,
+//GO(event_mm_free_,
+//GO(event_mm_malloc_,
+//GO(event_mm_realloc_,
+//GO(event_mm_strdup_,
+//GO(event_msgx,
+//GO(event_new,
+//GO(event_once,
+//GO(event_pending,
+//GO(event_priority_init,
+//GO(event_priority_set,
+//GO(event_reinit,
+//GO(event_remove_timer,
+//GO(event_remove_timer_nolock_,
+//GO(event_self_cbarg,
+GOM(event_set, vFEpiwpp)
+//GO(event_set_fatal_callback,
+//GO(event_set_log_callback,
+//GO(event_set_mem_functions,
+//GO(event_sock_err,
+//GO(event_sock_warn,
+//GO(event_strlcpy_,
+//GO(event_warn,
+//GO(event_warnx,
+//GO(evhttp_accept_socket,
+//GO(evhttp_accept_socket_with_handle,
+//GO(evhttp_add_header,
+//GO(evhttp_add_server_alias,
+//GO(evhttp_add_virtual_host,
+//GO(evhttp_bind_listener,
+//GO(evhttp_bind_socket,
+//GO(evhttp_bind_socket_with_handle,
+//GO(evhttp_bound_socket_get_fd,
+//GO(evhttp_bound_socket_get_listener,
+//GO(evhttp_cancel_request,
+//GO(evhttp_clear_headers,
+//GO(evhttp_connection_base_bufferevent_new,
+//GO(evhttp_connection_base_new,
+//GO(evhttp_connection_connect_,
+//GO(evhttp_connection_fail_,
+//GO(evhttp_connection_free,
+//GO(evhttp_connection_free_on_completion,
+//GO(evhttp_connection_get_addr,
+//GO(evhttp_connection_get_base,
+//GO(evhttp_connection_get_bufferevent,
+//GO(evhttp_connection_get_peer,
+//GO(evhttp_connection_get_server,
+//GO(evhttp_connection_new,
+//GO(evhttp_connection_reset_,
+//GO(evhttp_connection_set_base,
+//GO(evhttp_connection_set_closecb,
+//GO(evhttp_connection_set_family,
+//GO(evhttp_connection_set_flags,
+//GO(evhttp_connection_set_initial_retry_tv,
+//GO(evhttp_connection_set_local_address,
+//GO(evhttp_connection_set_local_port,
+//GO(evhttp_connection_set_max_body_size,
+//GO(evhttp_connection_set_max_headers_size,
+//GO(evhttp_connection_set_retries,
+//GO(evhttp_connection_set_timeout,
+//GO(evhttp_connection_set_timeout_tv,
+//GO(evhttp_decode_uri,
+//GO(evhttp_decode_uri_internal,
+//GO(evhttp_del_accept_socket,
+//GO(evhttp_del_cb,
+//GO(evhttp_encode_uri,
+//GO(evhttp_find_header,
+//GO(evhttp_foreach_bound_socket,
+//GO(evhttp_free,
+//GO(evhttp_htmlescape,
+//GO(evhttp_make_request,
+//GO(evhttp_new,
+//GO(evhttp_parse_firstline_,
+//GO(evhttp_parse_headers_,
+//GO(evhttp_parse_query,
+//GO(evhttp_parse_query_str,
+//GO(evhttp_remove_header,
+//GO(evhttp_remove_server_alias,
+//GO(evhttp_remove_virtual_host,
+//GO(evhttp_request_free,
+//GO(evhttp_request_get_command,
+//GO(evhttp_request_get_connection,
+//GO(evhttp_request_get_evhttp_uri,
+//GO(evhttp_request_get_host,
+//GO(evhttp_request_get_input_buffer,
+//GO(evhttp_request_get_input_headers,
+//GO(evhttp_request_get_output_buffer,
+//GO(evhttp_request_get_output_headers,
+//GO(evhttp_request_get_response_code,
+//GO(evhttp_request_get_response_code_line,
+//GO(evhttp_request_get_uri,
+//GO(evhttp_request_is_owned,
+//GO(evhttp_request_new,
+//GO(evhttp_request_own,
+//GO(evhttp_request_set_chunked_cb,
+//GO(evhttp_request_set_error_cb,
+//GO(evhttp_request_set_header_cb,
+//GO(evhttp_request_set_on_complete_cb,
+//GO(evhttp_response_code_,
+//GO(evhttp_send_error,
+//GO(evhttp_send_page_,
+//GO(evhttp_send_reply,
+//GO(evhttp_send_reply_chunk,
+//GO(evhttp_send_reply_chunk_with_cb,
+//GO(evhttp_send_reply_end,
+//GO(evhttp_send_reply_start,
+//GO(evhttp_set_allowed_methods,
+//GO(evhttp_set_bevcb,
+//GO(evhttp_set_cb,
+//GO(evhttp_set_default_content_type,
+//GO(evhttp_set_flags,
+//GO(evhttp_set_gencb,
+//GO(evhttp_set_max_body_size,
+//GO(evhttp_set_max_headers_size,
+//GO(evhttp_set_timeout,
+//GO(evhttp_set_timeout_tv,
+//GO(evhttp_start,
+//GO(evhttp_start_read_,
+//GO(evhttp_start_write_,
+//GO(evhttp_uridecode,
+//GO(evhttp_uriencode,
+//GO(evhttp_uri_free,
+//GO(evhttp_uri_get_fragment,
+//GO(evhttp_uri_get_host,
+//GO(evhttp_uri_get_path,
+//GO(evhttp_uri_get_port,
+//GO(evhttp_uri_get_query,
+//GO(evhttp_uri_get_scheme,
+//GO(evhttp_uri_get_userinfo,
+//GO(evhttp_uri_join,
+//GO(evhttp_uri_new,
+//GO(evhttp_uri_parse,
+//GO(evhttp_uri_parse_with_flags,
+//GO(evhttp_uri_set_flags,
+//GO(evhttp_uri_set_fragment,
+//GO(evhttp_uri_set_host,
+//GO(evhttp_uri_set_path,
+//GO(evhttp_uri_set_port,
+//GO(evhttp_uri_set_query,
+//GO(evhttp_uri_set_scheme,
+//GO(evhttp_uri_set_userinfo,
+//GO(evmap_check_integrity_,
+//GO(evmap_delete_all_,
+//GO(evmap_foreach_event_,
+//GO(evmap_io_active_,
+//GO(evmap_io_add_,
+//GO(evmap_io_clear_,
+//GO(evmap_io_del_,
+//GO(evmap_io_get_fdinfo_,
+//GO(evmap_io_initmap_,
+//GO(evmap_reinit_,
+//GO(evmap_signal_active_,
+//GO(evmap_signal_add_,
+//GO(evmap_signal_clear_,
+//GO(evmap_signal_del_,
+//GO(evmap_signal_initmap_,
+//GO(evrpc_add_hook,
+//GO(evrpc_free,
+//GO(evrpc_get_reply,
+//GO(evrpc_get_request,
+//GO(evrpc_hook_add_meta,
+//GO(evrpc_hook_find_meta,
+//GO(evrpc_hook_get_connection,
+//GO(evrpc_init,
+//GO(evrpc_make_request,
+//GO(evrpc_make_request_ctx,
+//GO(evrpc_pool_add_connection,
+//GO(evrpc_pool_free,
+//GO(evrpc_pool_new,
+//GO(evrpc_pool_remove_connection,
+//GO(evrpc_pool_set_timeout,
+//GO(evrpc_register_generic,
+//GO(evrpc_register_rpc,
+//GO(evrpc_remove_hook,
+//GO(evrpc_reqstate_free_,
+//GO(evrpc_request_done,
+//GO(evrpc_request_get_pool,
+//GO(evrpc_request_set_cb,
+//GO(evrpc_request_set_pool,
+//GO(evrpc_resume_request,
+//GO(evrpc_send_request_generic,
+//GO(evrpc_unregister_rpc,
+//GO(evsig_dealloc_,
+//GO(evsig_free_globals_,
+//GO(evsig_global_setup_locks_,
+//GO(evsig_init_,
+//GO(evsig_restore_handler_,
+//GO(evsig_set_base_,
+//GO(evsig_set_handler_,
+//GO(evtag_consume,
+//GO(evtag_decode_int,
+//GO(evtag_decode_int64,
+//GO(evtag_decode_tag,
+//GO(evtag_encode_int,
+//GO(evtag_encode_int64,
+//GO(evtag_encode_tag,
+//GO(evtag_init,
+//GO(evtag_marshal,
+//GO(evtag_marshal_buffer,
+//GO(evtag_marshal_int,
+//GO(evtag_marshal_int64,
+//GO(evtag_marshal_string,
+//GO(evtag_marshal_timeval,
+//GO(evtag_payload_length,
+//GO(evtag_peek,
+//GO(evtag_peek_length,
+//GO(evtag_unmarshal,
+//GO(evtag_unmarshal_fixed,
+//GO(evtag_unmarshal_header,
+//GO(evtag_unmarshal_int,
+//GO(evtag_unmarshal_int64,
+//GO(evtag_unmarshal_string,
+//GO(evtag_unmarshal_timeval,
+//DATAB(evthread_cond_fns_,
+//GO(evthread_debug_get_real_lock_,
+//GO(evthread_enable_lock_debugging,
+//GO(evthread_enable_lock_debuging,
+//GO(evthread_get_condition_callbacks,
+//GO(evthread_get_lock_callbacks,
+//DATAB(evthread_id_fn_,
+//GO(evthreadimpl_disable_lock_debugging_,
+//GO(evthread_is_debug_lock_held_,
+//DATAB(evthread_lock_debugging_enabled_,
+//DATAB(evthread_lock_fns_,
+//GO(evthread_make_base_notifiable,
+//GO(evthread_set_condition_callbacks,
+//GO(evthread_set_id_callback,
+//GO(evthread_set_lock_callbacks,
+//GO(evthread_setup_global_lock_,
+//GO(ev_token_bucket_cfg_free,
+//GO(ev_token_bucket_cfg_new,
+//GO(ev_token_bucket_get_tick_,
+//GO(ev_token_bucket_init_,
+//GO(ev_token_bucket_update_,
+//GO(evutil_accept4_,
+//GO(evutil_addrinfo_append_,
+//GO(evutil_adjust_hints_for_addrconfig_,
+//GO(evutil_ascii_strcasecmp,
+//GO(evutil_ascii_strncasecmp,
+//GO(evutil_closesocket,
+//GO(evutil_configure_monotonic_time,
+//GO(evutil_configure_monotonic_time_,
+//GO(evutil_date_rfc1123,
+//GO(evutil_ersatz_socketpair_,
+//GO(evutil_eventfd_,
+//GO(evutil_format_sockaddr_port_,
+//GO(evutil_freeaddrinfo,
+//GO(evutil_free_globals_,
+//GO(evutil_free_secure_rng_globals_,
+//GO(evutil_gai_strerror,
+//GO(evutil_getaddrinfo,
+//GO(evutil_getaddrinfo_async_,
+//GO(evutil_getaddrinfo_cancel_async_,
+//GO(evutil_getaddrinfo_common_,
+//GO(evutil_getenv_,
+//GO(evutil_gettime_monotonic,
+//GO(evutil_gettime_monotonic_,
+//GO(evutil_global_setup_locks_,
+//GO(evutil_hex_char_to_int_,
+//GO(evutil_inet_ntop,
+//GO(evutil_inet_pton,
+//GO(evutil_inet_pton_scope,
+//GO(EVUTIL_ISALNUM_,
+//GO(EVUTIL_ISALPHA_,
+//GO(EVUTIL_ISDIGIT_,
+//GO(EVUTIL_ISLOWER_,
+//GO(EVUTIL_ISPRINT_,
+//GO(EVUTIL_ISSPACE_,
+//GO(EVUTIL_ISUPPER_,
+//GO(EVUTIL_ISXDIGIT_,
+//GO(evutil_make_internal_pipe_,
+//GO(evutil_make_listen_socket_ipv6only,
+//GO(evutil_make_listen_socket_reuseable,
+//GO(evutil_make_listen_socket_reuseable_port,
+//GO(evutil_make_socket_closeonexec,
+//GO(evutil_make_socket_nonblocking,
+//GO(evutil_make_tcp_listen_socket_deferred,
+//GO(evutil_memclear_,
+//DATA(evutil_memset_volatile_,
+//GO(evutil_monotonic_timer_free,
+//GO(evutil_monotonic_timer_new,
+//GO(evutil_new_addrinfo_,
+//GO(evutil_open_closeonexec_,
+//GO(evutil_parse_sockaddr_port,
+//GO(evutil_read_file_,
+//GO(evutil_rtrim_lws_,
+//GO(evutil_secure_rng_add_bytes,
+//GO(evutil_secure_rng_get_bytes,
+//GO(evutil_secure_rng_global_setup_locks_,
+//GO(evutil_secure_rng_init,
+//GO(evutil_secure_rng_set_urandom_device_file,
+//GO(evutil_set_evdns_getaddrinfo_cancel_fn_,
+//GO(evutil_set_evdns_getaddrinfo_fn_,
+//GO(evutil_snprintf,
+//GO(evutil_sockaddr_cmp,
+//GO(evutil_sockaddr_is_loopback_,
+//GO(evutil_socket_,
+//GO(evutil_socket_connect_,
+//GO(evutil_socket_finished_connecting_,
+//GO(evutil_socketpair,
+//GO(evutil_strtoll,
+//GO(EVUTIL_TOLOWER_,
+//GO(EVUTIL_TOUPPER_,
+//GO(evutil_tv_to_msec_,
+//GO(evutil_usleep_,
+//GO(evutil_v4addr_is_local_,
+//GO(evutil_v6addr_is_local_,
+//GO(evutil_vsnprintf,
+//GO(evutil_weakrand_,
+//GO(evutil_weakrand_range_,
+//GO(evutil_weakrand_seed_,
+//GO(libevent_global_shutdown,
+//DATA(nil_eventop,
+//DATA(pollops,
+//DATA(selectops,
diff --git a/src/wrapped/wrappedflac.c b/src/wrapped/wrappedflac.c
index bc1919c..8f0f376 100644
--- a/src/wrapped/wrappedflac.c
+++ b/src/wrapped/wrappedflac.c
@@ -18,7 +18,12 @@
#include "myalign.h"
#include "bridge.h"
-const char* flacName = "libFLAC.so.8";
+#ifdef ANDROID
+ const char* flacName = "libFLAC.so";
+#else
+ const char* flacName = "libFLAC.so.8";
+#endif
+
#define LIBNAME flac
typedef struct {
diff --git a/src/wrapped/wrappedfontconfig.c b/src/wrapped/wrappedfontconfig.c
index b56e41c..9a5b2e7 100644
--- a/src/wrapped/wrappedfontconfig.c
+++ b/src/wrapped/wrappedfontconfig.c
@@ -18,7 +18,12 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
-const char* fontconfigName = "libfontconfig.so.1";
+#ifdef ANDROID
+ const char* fontconfigName = "libfontconfig.so";
+#else
+ const char* fontconfigName = "libfontconfig.so.1";
+#endif
+
#define LIBNAME fontconfig
#define ADDED_FUNCTIONS() \
@@ -45,7 +50,10 @@ EXPORT void* my_FcObjectSetBuild(x64emu_t* emu, void* first, uint64_t* b)
}
#define CUSTOM_INIT \
- getMy(lib);
+ getMy(lib); \
+ setNeededLibs(lib, 2, \
+ "libexpat.so.1", \
+ "libfreetype.so.6");
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedfontconfig_private.h b/src/wrapped/wrappedfontconfig_private.h
index 055db1b..5a61c63 100644
--- a/src/wrapped/wrappedfontconfig_private.h
+++ b/src/wrapped/wrappedfontconfig_private.h
@@ -41,7 +41,7 @@ GO(FcConfigAppFontAddDir, iFpp)
GO(FcConfigAppFontAddFile, iFpp)
GO(FcConfigAppFontClear, vFp)
GO(FcConfigBuildFonts, iFp)
-//GO(FcConfigCreate,
+GO(FcConfigCreate, pFv)
GO(FcConfigDestroy, vFp)
GO(FcConfigEnableHome, iFi)
//GO(FcConfigFilename,
@@ -163,7 +163,7 @@ GO(FcPatternGetString, uFppip)
GO(FcPatternHash, uFp)
GO(FcPatternPrint, vFp)
GO(FcPatternReference, vFp)
-//GO(FcPatternRemove,
+GO(FcPatternRemove, iFppi)
GO(FcPatternVaBuild, pFpp)
GO(FcStrBasename, pFp)
GO(FcStrCmp, iFpp)
diff --git a/src/wrapped/wrappedfreetype.c b/src/wrapped/wrappedfreetype.c
index 4ced9be..86706b4 100644
--- a/src/wrapped/wrappedfreetype.c
+++ b/src/wrapped/wrappedfreetype.c
@@ -18,7 +18,13 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
-const char* freetypeName = "libfreetype.so.6";
+const char* freetypeName =
+#ifdef ANDROID
+ "libfreetype.so"
+#else
+ "libfreetype.so.6"
+#endif
+ ;
#define LIBNAME freetype
typedef void (*vFp_t)(void*);
diff --git a/src/wrapped/wrappedfreetype_private.h b/src/wrapped/wrappedfreetype_private.h
index 4095693..7ec258d 100644
--- a/src/wrapped/wrappedfreetype_private.h
+++ b/src/wrapped/wrappedfreetype_private.h
@@ -154,7 +154,7 @@ GO(FT_Select_Size, iFpi)
GO(FT_Set_Charmap, iFpp)
GO(FT_Set_Char_Size, iFplluu)
//GO(FT_Set_Debug_Hook,
-//GO(FT_Set_Default_Properties,
+GO(FT_Set_Default_Properties, vFp)
//GO(FT_Set_MM_Blend_Coordinates,
GO(FT_Set_MM_Design_Coordinates, iFpup)
GO(FT_Set_Pixel_Sizes, iFpuu)
diff --git a/src/wrapped/wrappedgbm.c b/src/wrapped/wrappedgbm.c
index 39f000a..c060c10 100644
--- a/src/wrapped/wrappedgbm.c
+++ b/src/wrapped/wrappedgbm.c
@@ -6,13 +6,70 @@
#include "wrappedlibs.h"
+#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
const char* gbmName = "libgbm.so.1";
#define LIBNAME gbm
-#include "wrappedlib_init.h"
+#define ADDED_FUNCTIONS() \
+
+#include "generated/wrappedgbmtypes.h"
+
+#include "wrappercallback.h"
+
+// utility functions
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3) \
+GO(4)
+
+// destroy_user_data
+#define GO(A) \
+static uintptr_t my_destroy_user_data_fct_##A = 0; \
+static void my_destroy_user_data_##A(void* a, void* b) \
+{ \
+ RunFunctionFmt(my_destroy_user_data_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* find_destroy_user_data_Fct(void* fct)
+{
+ if(!fct) return NULL;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_destroy_user_data_fct_##A == (uintptr_t)fct) return my_destroy_user_data_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_destroy_user_data_fct_##A == 0) {my_destroy_user_data_fct_##A = (uintptr_t)fct; return my_destroy_user_data_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for libgbm destroy_user_data callback\n");
+ return NULL;
+}
+#undef SUPER
+
+EXPORT void my_gbm_bo_set_user_data(x64emu_t* emu, void* bo, void* data, void *f)
+{
+ my->gbm_bo_set_user_data(bo, data, find_destroy_user_data_Fct(f));
+}
+
+#define CUSTOM_INIT \
+ getMy(lib);
+
+#define CUSTOM_FINI \
+ freeMy();
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgbm_private.h b/src/wrapped/wrappedgbm_private.h
index c5bd513..30200dc 100644
--- a/src/wrapped/wrappedgbm_private.h
+++ b/src/wrapped/wrappedgbm_private.h
@@ -23,7 +23,7 @@ GO(gbm_bo_get_user_data, pFp)
GO(gbm_bo_get_width, uFp)
GO(gbm_bo_import, pFpupu)
GO(gbm_bo_map, pFpuuuuupp)
-//GOM(gbm_bo_set_user_data, vFEppB)
+GOM(gbm_bo_set_user_data, vFEppp)
GO(gbm_bo_unmap, vFpp)
GO(gbm_bo_write, iFppL)
GO(gbm_create_device, pFi)
diff --git a/src/wrapped/wrappedgdk3.c b/src/wrapped/wrappedgdk3.c
index aea28c6..0cfc6fc 100644
--- a/src/wrapped/wrappedgdk3.c
+++ b/src/wrapped/wrappedgdk3.c
@@ -171,6 +171,17 @@ EXPORT uint32_t my3_gdk_threads_add_idle_full(x64emu_t* emu, int priority, void*
return my->gdk_threads_add_idle_full(priority, findGSourceFunc(f), data, findGDestroyNotifyFct(d));
}
+EXPORT uint32_t my3_gdk_threads_add_idle(x64emu_t* emu, void* f, void* data)
+{
+ return my->gdk_threads_add_idle(findGSourceFunc(f), data);
+}
+
+EXPORT uint32_t my3_gdk_threads_add_timeout_full(x64emu_t* emu, int priotity, uint32_t interval, void* f, void* data, void* d)
+{
+ return my->gdk_threads_add_timeout_full(priotity, interval, findGSourceFunc(f), data, findGDestroyNotifyFct(d));
+}
+
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
diff --git a/src/wrapped/wrappedgdk3_private.h b/src/wrapped/wrappedgdk3_private.h
index 97455ee..89a63b5 100644
--- a/src/wrapped/wrappedgdk3_private.h
+++ b/src/wrapped/wrappedgdk3_private.h
@@ -89,15 +89,18 @@ GO(gdk_device_get_mode, uFp)
GO(gdk_device_get_name, pFp)
GO(gdk_device_get_n_axes, iFp)
GO(gdk_device_get_n_keys, iFp)
+GO(gdk_device_get_position, vFpppp)
GO(gdk_device_get_source, uFp)
GO(gdk_device_get_state, vFpppp)
GO(gdk_device_get_type, iFv)
GO(gdk_device_set_axis_use, vFpuu)
+GO(gdk_device_manager_get_client_pointer, pFp)
GO(gdk_device_manager_get_type, lFv)
GO(gdk_device_set_key, vFpuuu)
GO(gdk_device_set_mode, iFpu)
GO(gdk_device_set_source, vFpi)
GO(gdk_devices_list, pFv)
+GO(gdk_device_ungrab, vFpu)
//GOM(gdk_display_add_client_message_filter, vFEpppp)
GO(gdk_display_beep, vFp)
GO(gdk_display_close, vFp)
@@ -108,11 +111,16 @@ GO(gdk_display_get_default_cursor_size, uFp)
GO(gdk_display_get_default_group, pFp)
GO(gdk_display_get_default_screen, pFp)
GO(gdk_display_get_default_seat, pFp)
+GO(gdk_display_get_device_manager, pFp)
GO(gdk_display_get_event, pFp)
GO(gdk_display_get_maximal_cursor_size, vFppp)
GO(gdk_display_get_name, pFp)
+GO(gdk_display_get_monitor, pFpi)
+GO(gdk_display_get_monitors, pFp)
+GO(gdk_display_get_n_monitors, iFp)
GO(gdk_display_get_n_screens, iFp)
GO(gdk_display_get_pointer, vFppppp)
+GO(gdk_display_get_primary_monitor, pFp)
GO(gdk_display_get_screen, pFpi)
GO(gdk_display_get_type, iFv)
GO(gdk_display_get_window_at_pointer, pFppp)
@@ -371,6 +379,18 @@ GO(gdk_keyval_to_upper, uFu)
GO(gdk_line_style_get_type, iFv)
GO(gdk_list_visuals, pFv)
//GO(gdk_mbstowcs,
+GO(gdk_monitor_get_connector, pFp)
+GO(gdk_monitor_get_description, pFp)
+GO(gdk_monitor_get_display, pFp)
+GO(gdk_monitor_get_geometry, vFpp)
+GO(gdk_monitor_get_height_mm, iFp)
+GO(gdk_monitor_get_manufacturer, pFp)
+GO(gdk_monitor_get_model, pFp)
+GO(gdk_monitor_get_refresh_rate, iFp)
+GO(gdk_monitor_get_scale_factor, iFp)
+GO(gdk_monitor_get_subpixel_layout, uFp)
+GO(gdk_monitor_get_width_mm, iFp)
+GO(gdk_monitor_is_valid, iFp)
GO(gdk_memory_texture_new, pFiiipL)
GO(gdk_modifier_type_get_type, iFv)
GO(gdk_net_wm_supports, iFp)
@@ -459,7 +479,10 @@ GO(gdk_region_subtract, vFpp)
GO(gdk_region_union, vFpp)
GO(gdk_region_union_with_rect, vFpp)
GO(gdk_region_xor, vFpp)
-GO(gdk_rgba_get_type, lFv)
+GO(gdk_rgba_free, vFp)
+GO(gdk_rgba_get_type, LFv)
+GO(gdk_rgba_parse, iFpp)
+GO(gdk_rgba_to_string, pFp)
GO(gdk_rgb_cmap_free, vFp)
GO(gdk_rgb_cmap_new, pFpi)
GO(gdk_rgb_colormap_ditherable, iFp)
@@ -489,6 +512,7 @@ GO(gdk_screen_get_monitor_geometry, vFpip)
GO(gdk_screen_get_monitor_height_mm, iFpi)
GO(gdk_screen_get_monitor_plug_name, pFpi)
GO(gdk_screen_get_monitor_width_mm, iFpi)
+GO(gdk_screen_get_monitor_workarea, vFpip)
GO(gdk_screen_get_n_monitors, iFp)
GO(gdk_screen_get_number, iFp)
GO(gdk_screen_get_primary_monitor, iFp)
@@ -564,10 +588,10 @@ GO(gdk_text_property_to_utf8_list_for_display, iFppipip)
GO(gdk_texture_download, vFppL)
GO(gdk_texture_get_width, uFp)
GO(gdk_texture_get_height, uFp)
-//GOM(gdk_threads_add_idle, uFEpp)
+GOM(gdk_threads_add_idle, uFEpp)
GOM(gdk_threads_add_idle_full, uFEippp)
//GOM(gdk_threads_add_timeout, uFEupp)
-//GOM(gdk_threads_add_timeout_full, uFEiuppp)
+GOM(gdk_threads_add_timeout_full, uFEiuppp)
//GOM(gdk_threads_add_timeout_seconds, uFEupp)
//GOM(gdk_threads_add_timeout_seconds_full, uFEiuppp)
GO(gdk_threads_enter, vFv)
@@ -599,6 +623,7 @@ GO(gdk_visual_get_type, LFv)
GO(gdk_visual_get_visual_type, uFp)
GO(gdk_visual_type_get_type, iFv)
GO(gdk_wayland_toplevel_set_transient_for_exported, iFpp)
+GO(gdk_wayland_window_get_type, LFv)
GO(gdk_wayland_window_set_transient_for_exported, iFpp)
//GO(gdk_wcstombs,
GOM(gdk_window_add_filter, vFEppp)
diff --git a/src/wrapped/wrappedgdkx112.c b/src/wrapped/wrappedgdkx112.c
index cb62731..9b7bde7 100644
--- a/src/wrapped/wrappedgdkx112.c
+++ b/src/wrapped/wrappedgdkx112.c
@@ -57,7 +57,52 @@ static void* findFilterFct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for gtk-2 GdkFilterFunc callback\n");
return NULL;
}
+// GSourceFunc
+#define GO(A) \
+static uintptr_t my_GSourceFunc_fct_##A = 0; \
+static int my_GSourceFunc_##A(void* a) \
+{ \
+ return (int)RunFunctionFmt(my_GSourceFunc_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGSourceFunc(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GSourceFunc_fct_##A == (uintptr_t)fct) return my_GSourceFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GSourceFunc_fct_##A == 0) {my_GSourceFunc_fct_##A = (uintptr_t)fct; return my_GSourceFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gdk2 GSourceFunc callback\n");
+ return NULL;
+}
+// GDestroyNotify
+#define GO(A) \
+static uintptr_t my_GDestroyNotify_fct_##A = 0; \
+static void my_GDestroyNotify_##A(void* data) \
+{ \
+ RunFunctionFmt(my_GDestroyNotify_fct_##A, "p", data); \
+}
+SUPER()
+#undef GO
+static void* findGDestroyNotifyFct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GDestroyNotify_fct_##A == (uintptr_t)fct) return my_GDestroyNotify_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GDestroyNotify_fct_##A == 0) {my_GDestroyNotify_fct_##A = (uintptr_t)fct; return my_GDestroyNotify_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gdk2 GDestroyNotify callback\n");
+ return NULL;
+}
+#undef SUPER
static void my_event_handler(void* event, my_signal_t* sig)
{
@@ -120,6 +165,11 @@ EXPORT void my_gdk_window_remove_filter(x64emu_t* emu, void* window, void* f, vo
my->gdk_window_remove_filter(window, findFilterFct(f), data);
}
+EXPORT uint32_t my_gdk_threads_add_timeout_full(x64emu_t* emu, int priotity, uint32_t interval, void* f, void* data, void* d)
+{
+ return my->gdk_threads_add_timeout_full(priotity, interval, findGSourceFunc(f), data, findGDestroyNotifyFct(d));
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
diff --git a/src/wrapped/wrappedgdkx112_private.h b/src/wrapped/wrappedgdkx112_private.h
index f9c4d6b..1a90ae4 100644
--- a/src/wrapped/wrappedgdkx112_private.h
+++ b/src/wrapped/wrappedgdkx112_private.h
@@ -533,7 +533,7 @@ GO(gdk_text_width_wc, iFppi)
//GOM(gdk_threads_add_idle, uFEpp)
//GOM(gdk_threads_add_idle_full, uFEippp)
//GOM(gdk_threads_add_timeout, uFEupp)
-//GOM(gdk_threads_add_timeout_full, uFEiuppp)
+GOM(gdk_threads_add_timeout_full, uFEiuppp)
//GOM(gdk_threads_add_timeout_seconds, uFEupp)
//GOM(gdk_threads_add_timeout_seconds_full, uFEiuppp)
GO(gdk_threads_enter, vFv)
diff --git a/src/wrapped/wrappedgio2.c b/src/wrapped/wrappedgio2.c
index e4837e7..2556c7b 100644
--- a/src/wrapped/wrappedgio2.c
+++ b/src/wrapped/wrappedgio2.c
@@ -616,6 +616,11 @@ EXPORT void my_g_task_return_new_error(x64emu_t* emu, void* task, uint32_t domai
free(tmp);
}
+EXPORT void my_g_input_stream_read_async(x64emu_t* emu, void* stream, void* buffer, size_t count, int io_prio, void* cancel, void* f, void* data)
+{
+ my->g_input_stream_read_async(stream, buffer, count, io_prio, cancel, findGAsyncReadyCallbackFct(f), data);
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
diff --git a/src/wrapped/wrappedgio2_private.h b/src/wrapped/wrappedgio2_private.h
index 560b251..c97a314 100644
--- a/src/wrapped/wrappedgio2_private.h
+++ b/src/wrapped/wrappedgio2_private.h
@@ -952,11 +952,11 @@ GO(g_input_stream_has_pending, iFp)
//GO(g_input_stream_is_closed,
GO(g_input_stream_read, lFppLpp)
GO(g_input_stream_read_all, iFppLppp)
-//GO(g_input_stream_read_async,
+GOM(g_input_stream_read_async, vFEppLippp)
GO(g_input_stream_read_bytes, pFpLpp)
//GO(g_input_stream_read_bytes_async,
GO(g_input_stream_read_bytes_finish, pFppp)
-//GO(g_input_stream_read_finish,
+GO(g_input_stream_read_finish, lFppp)
GO(g_input_stream_set_pending, iFpp)
GO(g_input_stream_skip, lFpLpp)
//GO(g_input_stream_skip_async,
@@ -1228,7 +1228,7 @@ GO(g_proxy_address_get_destination_port, WFp)
//GO(g_proxy_address_get_destination_protocol,
//GO(g_proxy_address_get_password,
//GO(g_proxy_address_get_protocol,
-//GO(g_proxy_address_get_type,
+GO(g_proxy_address_get_type, LFv)
GO(g_proxy_address_get_uri, pFp)
//GO(g_proxy_address_get_username,
GO(g_proxy_address_new, pFpWppWpp)
@@ -1238,7 +1238,7 @@ GO(g_proxy_connect_finish, pFppp)
GO(g_proxy_get_default_for_protocol, pFp)
//GO(g_proxy_get_type,
GO(g_proxy_resolver_get_default, pFv)
-//GO(g_proxy_resolver_get_type,
+GO(g_proxy_resolver_get_type, LFv)
GO(g_proxy_resolver_is_supported, iFp)
GO(g_proxy_resolver_lookup, pFpppp)
//GO(g_proxy_resolver_lookup_async,
@@ -1252,7 +1252,7 @@ GO(g_remote_action_group_change_action_state_full, vFpppp)
//GO(g_resolver_free_addresses,
GO(g_resolver_free_targets, vFp)
GO(g_resolver_get_default, pFv)
-//GO(g_resolver_get_type,
+GO(g_resolver_get_type, LFv)
GO(g_resolver_lookup_by_address, pFpppp)
//GO(g_resolver_lookup_by_address_async,
GO(g_resolver_lookup_by_address_finish, pFppp)
@@ -1424,7 +1424,7 @@ GO(g_socket_address_enumerator_next, pFppp)
GO(g_socket_address_enumerator_next_finish, pFppp)
GO(g_socket_address_get_family, uFp)
GO(g_socket_address_get_native_size, lFp)
-//GO(g_socket_address_get_type,
+GO(g_socket_address_get_type, LFv)
//GO(g_socket_address_new_from_native,
GO(g_socket_address_to_native, iFppLp)
GO(g_socket_bind, iFppip)
@@ -1452,7 +1452,7 @@ GO(g_socket_client_get_socket_type, uFp)
GO(g_socket_client_get_timeout, uFp)
GO(g_socket_client_get_tls, iFp)
GO(g_socket_client_get_tls_validation_flags, uFp)
-//GO(g_socket_client_get_type,
+GO(g_socket_client_get_type, LFv)
GO(g_socket_client_new, pFv)
//GO(g_socket_client_set_enable_proxy,
GO(g_socket_client_set_family, vFpu)
@@ -1489,7 +1489,7 @@ GO(g_socket_control_message_get_size, LFp)
//GO(g_socket_control_message_get_type,
GO(g_socket_control_message_serialize, vFpp)
//GO(g_socket_create_source,
-//GO(g_socket_family_get_type,
+GO(g_socket_family_get_type, LFv)
GO(g_socket_get_available_bytes, lFp)
//GO(g_socket_get_blocking,
//GO(g_socket_get_broadcast,
@@ -1507,7 +1507,7 @@ GO(g_socket_get_remote_address, pFpp)
GO(g_socket_get_socket_type, uFp)
//GO(g_socket_get_timeout,
//GO(g_socket_get_ttl,
-//GO(g_socket_get_type,
+GO(g_socket_get_type, LFv)
//GO(g_socket_is_closed,
//GO(g_socket_is_connected,
//GO(g_socket_join_multicast_group,
@@ -1539,7 +1539,7 @@ GO(g_socket_send, lFppLpp)
GO(g_socket_send_message, lFpppipiipp)
GO(g_socket_send_to, lFpppLpp)
GO(g_socket_send_with_blocking, lFppLipp)
-//GO(g_socket_service_get_type,
+GO(g_socket_service_get_type, LFv)
GO(g_socket_service_is_active, iFp)
GO(g_socket_service_new, pFv)
//GO(g_socket_service_start,
@@ -1682,7 +1682,7 @@ GO(g_tls_backend_get_default_database, pFp)
//GO(g_tls_backend_supports_tls,
//GO(g_tls_certificate_flags_get_type,
GO(g_tls_certificate_get_issuer, pFp)
-//GO(g_tls_certificate_get_type,
+GO(g_tls_certificate_get_type, LFv)
GO(g_tls_certificate_is_same, iFpp)
GO(g_tls_certificate_list_new_from_file, pFpp)
GO(g_tls_certificate_new_from_file, pFpp)
@@ -1707,7 +1707,7 @@ GO(g_tls_connection_get_peer_certificate, pFp)
GO(g_tls_connection_get_peer_certificate_errors, uFp)
GO(g_tls_connection_get_rehandshake_mode, uFp)
GO(g_tls_connection_get_require_close_notify, iFp)
-//GO(g_tls_connection_get_type,
+GO(g_tls_connection_get_type, LFv)
//GO(g_tls_connection_get_use_system_certdb,
GO(g_tls_connection_handshake, iFppp)
//GO(g_tls_connection_handshake_async,
@@ -1719,7 +1719,7 @@ GO(g_tls_connection_set_rehandshake_mode, vFpu)
GO(g_tls_connection_set_require_close_notify, vFpi)
//GO(g_tls_connection_set_use_system_certdb,
GO(g_tls_database_create_certificate_handle, pFpp)
-//GO(g_tls_database_get_type,
+GO(g_tls_database_get_type, LFv)
GO(g_tls_database_lookup_certificate_for_handle, pFpppupp)
//GO(g_tls_database_lookup_certificate_for_handle_async,
//GO(g_tls_database_lookup_certificate_for_handle_finish,
@@ -1741,7 +1741,7 @@ GO(g_tls_file_database_new, pFpp)
GO(g_tls_interaction_ask_password, uFpppp)
//GO(g_tls_interaction_ask_password_async,
//GO(g_tls_interaction_ask_password_finish,
-//GO(g_tls_interaction_get_type,
+GO(g_tls_interaction_get_type, LFv)
//GO(g_tls_interaction_invoke_ask_password,
//GO(g_tls_interaction_invoke_request_certificate,
GO(g_tls_interaction_request_certificate, uFppupp)
diff --git a/src/wrapped/wrappedglib2.c b/src/wrapped/wrappedglib2.c
index 5614314..9dd59d7 100644
--- a/src/wrapped/wrappedglib2.c
+++ b/src/wrapped/wrappedglib2.c
@@ -664,6 +664,28 @@ static void* reverseGOptionArgFct(void* fct)
#undef GO
return (void*)AddCheckBridge(my_lib->w.bridge, iFpppp, fct, 0, "GOptionArgFunc");
}
+// GOptionParse ...
+#define GO(A) \
+static uintptr_t my_GOptionParse_fct_##A = 0; \
+static int my_GOptionParse_##A(void* a, void* b, void* c, void* d) \
+{ \
+ return (int)RunFunctionFmt(my_GOptionParse_fct_##A, "pppp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* findGOptionParseFct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GOptionParse_fct_##A == (uintptr_t)fct) return my_GOptionParse_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GOptionParse_fct_##A == 0) {my_GOptionParse_fct_##A = (uintptr_t)fct; return my_GOptionParse_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for glib2 GOptionParse callback\n");
+ return NULL;
+}
// GNodeTraverseFunc ...
#define GO(A) \
static uintptr_t my_GNodeTraverseFunc_fct_##A = 0; \
@@ -1393,6 +1415,26 @@ EXPORT void* my_g_list_insert_sorted_with_data(x64emu_t* emu, void* list, void*
return my->g_list_insert_sorted_with_data(list, data, findGCompareDataFuncFct(f), user);
}
+EXPORT void my_g_option_group_set_parse_hooks(x64emu_t* emu, void* group, void* preparse, void* postparse)
+{
+ my->g_option_group_set_parse_hooks(group, findGOptionParseFct(preparse), findGOptionParseFct(postparse));
+}
+
+EXPORT void* my_g_thread_new(x64emu_t* emu, void* name, void* f, void* data)
+{
+ return my->g_thread_new(name, findGThreadFuncFct(f), data);
+}
+
+EXPORT void my_g_queue_foreach(x64emu_t* emu, void* queue, void* f, void* data)
+{
+ my->g_queue_foreach(queue, findGFuncFct(f), data);
+}
+
+EXPORT void* my_g_once_impl(x64emu_t* emu, void* once, void* f, void* arg)
+{
+ return my->g_once_impl(once, findGThreadFuncFct(f), arg);
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
diff --git a/src/wrapped/wrappedglib2_private.h b/src/wrapped/wrappedglib2_private.h
index 6ee782f..1f64bd1 100644
--- a/src/wrapped/wrappedglib2_private.h
+++ b/src/wrapped/wrappedglib2_private.h
@@ -180,7 +180,7 @@ GO(g_cache_remove, vFpp)
//GO(g_cache_value_foreach,
GO(g_chdir, iFp)
GO(g_checksum_copy, pFp)
-//GO(g_checksum_free,
+GO(g_checksum_free, vFp)
GO(g_checksum_get_digest, vFppp)
GO(g_checksum_get_string, pFp)
GO(g_checksum_new, pFu)
@@ -324,7 +324,7 @@ GO(g_date_time_to_timeval, iFpp)
GO(g_date_time_to_timezone, pFpp)
GO(g_date_time_to_unix, lFp)
GO(g_date_time_to_utc, pFp)
-//GO(g_date_time_unref,
+GO(g_date_time_unref, vFp)
GO(g_date_to_struct_tm, vFpp)
GO(g_date_valid, iFp)
GO(g_date_valid_day, iFC)
@@ -751,10 +751,10 @@ GO(g_node_push_allocator, vFp)
GOM(g_node_traverse, vFEpiiipp)
//GO(g_node_unlink,
GO(g_nullify_pointer, vFp)
-//GO(g_once_impl,
+GOM(g_once_impl, pFEppp)
GO(g_once_init_enter, iFp)
GO(g_once_init_enter_impl, iFp)
-GO(g_once_init_leave, vFpi)
+GO(g_once_init_leave, vFpL)
GO(g_on_error_query, vFp)
GO(g_on_error_stack_trace, vFp)
GO(g_open, iFpii)
@@ -785,7 +785,7 @@ GO(g_option_group_free, vFp)
GOM(g_option_group_new, pFEppppp)
GO(g_option_group_ref, pFp) // 2.44+
//GOM(g_option_group_set_error_hook, vFEpB)
-//GOM(g_option_group_set_parse_hooks, vFEpBB)
+GOM(g_option_group_set_parse_hooks, vFEppp)
//GOM(g_option_group_set_translate_func, vFEpBpB)
GO(g_option_group_set_translation_domain, vFpp)
GO(g_option_group_unref, vFp) // 2.44+
@@ -845,7 +845,7 @@ GO(g_queue_copy, pFp)
GO(g_queue_delete_link, vFpp)
GO(g_queue_find, pFpp)
GOM(g_queue_find_custom, pFEppp)
-//GOM(g_queue_foreach, vFEpBp)
+GOM(g_queue_foreach, vFEppp)
GO(g_queue_free, vFp)
//GOM(g_queue_free_full, vFEpB)
GO(g_queue_get_length, uFp)
@@ -1211,6 +1211,7 @@ GO(g_str_to_ascii, pFpp)
GO(g_strtod, dFpp)
GO(g_str_tokenize_and_fold, pFppp)
GO(g_strup, pFp)
+GO(g_strv_contains, iFpp)
GO(g_strv_length, uFp)
//GO(g_test_add_data_func,
//GO(g_test_add_data_func_full,
@@ -1269,7 +1270,7 @@ GOM(g_thread_foreach, vFEpp)
GO(g_thread_get_initialized, iFv)
//GO(g_thread_init_glib,
GO(g_thread_join, pFp)
-//GO(g_thread_new,
+GOM(g_thread_new, pFEppp)
//GO(g_thread_pool_free,
GO(g_thread_pool_get_max_idle_time, uFv)
//GO(g_thread_pool_get_max_threads,
@@ -1396,9 +1397,12 @@ GO(g_unlink, iFp)
GO(g_unsetenv, vFp)
GO(g_uri_escape_string, pFppi)
GO(g_uri_list_extract_uris, pFp)
+GO(g_uri_parse, pFpip)
GO(g_uri_parse_scheme, pFp)
+GO(g_uri_to_string_partial, pFpi)
GO(g_uri_unescape_segment, pFppp)
GO(g_uri_unescape_string, pFpp)
+GO(g_uri_unref, vFp)
GO(g_usleep, vFL)
GO(g_utf16_to_ucs4, pFplppp)
GO(g_utf16_to_utf8, pFplppp)
diff --git a/src/wrapped/wrappedgnutls.c b/src/wrapped/wrappedgnutls.c
index dd4cde2..1edf28d 100644
--- a/src/wrapped/wrappedgnutls.c
+++ b/src/wrapped/wrappedgnutls.c
@@ -18,7 +18,13 @@
#include "emu/x64emu_private.h"
#include "callback.h"
-const char* gnutlsName = "libgnutls.so.30";
+const char* gnutlsName =
+#if ANDROID
+ "libgnutls.so"
+#else
+ "libgnutls.so.30"
+#endif
+ ;
#define LIBNAME gnutls
#include "generated/wrappedgnutlstypes.h"
diff --git a/src/wrapped/wrappedgobject2.c b/src/wrapped/wrappedgobject2.c
index d51a736..6a30df4 100644
--- a/src/wrapped/wrappedgobject2.c
+++ b/src/wrapped/wrappedgobject2.c
@@ -29,6 +29,7 @@ typedef void*(*pFL_t)(size_t);
GO(g_object_get_type, LFv_t) \
GO(g_initially_unowned_get_type, LFv_t) \
GO(g_type_name, pFL_t) \
+ GO(g_type_parent, LFv_t) \
GO(g_type_class_peek, pFL_t) \
#include "generated/wrappedgobject2types.h"
@@ -541,20 +542,22 @@ static my_GParamSpecTypeInfo_t* findFreeGParamSpecTypeInfo(my_GParamSpecTypeInfo
// GInterfaceInitFunc
#define GO(A) \
static uintptr_t my_GInterfaceInitFunc_fct_##A = 0; \
+static size_t my_GInterfaceInitFunc_klass_##A = 0; \
static void my_GInterfaceInitFunc_##A(void* src, void* dst) \
{ \
- RunFunctionFmt(my_GInterfaceInitFunc_fct_##A, "pp", src, dst); \
+ RunFunctionFmt(my_GInterfaceInitFunc_fct_##A, "pp", src, dst); \
+ unwrapGTKInterface(src, my_GInterfaceInitFunc_klass_##A); \
}
SUPER()
#undef GO
-static void* findGInterfaceInitFuncFct(void* fct)
+static void* findGInterfaceInitFuncFct(void* fct, size_t klass)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
- #define GO(A) if(my_GInterfaceInitFunc_fct_##A == (uintptr_t)fct) return my_GInterfaceInitFunc_##A;
+ #define GO(A) if(my_GInterfaceInitFunc_fct_##A == (uintptr_t)fct && my_GInterfaceInitFunc_klass_##A == klass) return my_GInterfaceInitFunc_##A;
SUPER()
#undef GO
- #define GO(A) if(my_GInterfaceInitFunc_fct_##A == 0) {my_GInterfaceInitFunc_fct_##A = (uintptr_t)fct; return my_GInterfaceInitFunc_##A; }
+ #define GO(A) if(my_GInterfaceInitFunc_fct_##A == 0) {my_GInterfaceInitFunc_fct_##A = (uintptr_t)fct; my_GInterfaceInitFunc_klass_##A = klass; return my_GInterfaceInitFunc_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for gobject GInterfaceInitFunc callback\n");
@@ -713,8 +716,10 @@ EXPORT void* my_g_object_new_valist(x64emu_t* emu, size_t type, void* first, x64
EXPORT size_t my_g_type_register_static(x64emu_t* emu, size_t parent, void* name, my_GTypeInfo_t* info, int flags)
{
-
- return my->g_type_register_static(parent, name, findFreeGTypeInfo(info, parent), flags);
+ size_t ret = my->g_type_register_static(parent, name, findFreeGTypeInfo(info, parent), flags);
+ printf_log(LOG_DEBUG, "Registered %s as 0x%zx\n", name, ret);
+ addRegisteredClass(ret, name);
+ return ret;
}
EXPORT size_t my_g_type_register_fundamental(x64emu_t* emu, size_t parent, void* name, my_GTypeInfo_t* info, void* finfo, int flags)
@@ -767,7 +772,7 @@ typedef struct my_GInterfaceInfo_s {
EXPORT void my_g_type_add_interface_static(x64emu_t* emu, size_t instance_type, size_t interface_type, my_GInterfaceInfo_t* info)
{
my_GInterfaceInfo_t i = {0};
- i.interface_init = findGInterfaceInitFuncFct(info->interface_init);
+ i.interface_init = findGInterfaceInitFuncFct(info->interface_init, interface_type);
i.interface_finalize = findGInterfaceFinalizeFuncFct(info->interface_finalize);
i.data = info->data;
my->g_type_add_interface_static(instance_type, interface_type, &i);
@@ -906,6 +911,7 @@ EXPORT void* my_g_type_value_table_peek(x64emu_t* emu, size_t type)
SetGInitiallyUnownedID(my->g_initially_unowned_get_type()); \
SetGTypeName(my->g_type_name); \
SetGClassPeek(my->g_type_class_peek); \
+ SetGTypeParent(my->g_type_parent); \
setNeededLibs(lib, 1, "libglib-2.0.so.0");
#define CUSTOM_FINI \
diff --git a/src/wrapped/wrappedgobject2_private.h b/src/wrapped/wrappedgobject2_private.h
index b81d036..3eb648b 100644
--- a/src/wrapped/wrappedgobject2_private.h
+++ b/src/wrapped/wrappedgobject2_private.h
@@ -183,7 +183,7 @@ GO(g_param_spec_int, pFpppiiii)
GO(g_param_spec_int64, pFpppllli)
GO(g_param_spec_internal, pFLpppi)
GO(g_param_spec_long, pFpppllli)
-GO(g_param_spec_object, pFpppii)
+GO(g_param_spec_object, pFpppLi)
GO(g_param_spec_override, pFpp)
GO(g_param_spec_param, pFpppii)
GO(g_param_spec_pointer, pFpppi)
@@ -281,27 +281,27 @@ GO(g_type_check_instance_is_fundamentally_a, iFpL)
GO(g_type_check_is_value_type, iFL)
GO(g_type_check_value, LFp)
GO(g_type_check_value_holds, iFpL)
-GO(g_type_children, pFip)
+GO(g_type_children, pFLp)
GO(g_type_class_add_private, vFpL)
GO(g_type_class_adjust_private_offset, vFpp)
GO(g_type_class_get_instance_private_offset, iFp)
GO(g_type_class_get_private, pFpL)
-GO(g_type_class_peek, pFi)
+GO(g_type_class_peek, pFL)
GOM(g_type_class_peek_parent, pFEp)
-GO(g_type_class_peek_static, pFi)
+GO(g_type_class_peek_static, pFL)
GO(g_type_class_ref, pFp)
GO(g_type_class_unref, vFp)
GO(g_type_class_unref_uncached, vFp)
GO(g_type_create_instance, pFL)
GO(g_type_default_interface_peek, pFL)
-GO(g_type_default_interface_ref, pFi)
+GO(g_type_default_interface_ref, pFL)
GO(g_type_default_interface_unref, vFp)
GO(g_type_depth, uFL)
-GO(g_type_ensure, vFi)
+GO(g_type_ensure, vFL)
GO(g_type_free_instance, vFp)
-GO(g_type_from_name, iFp)
+GO(g_type_from_name, LFp)
GO(g_type_fundamental, LFL)
-GO(g_type_fundamental_next, iFv)
+GO(g_type_fundamental_next, LFv)
//GOM(g_type_get_plugin, pFEi) // GTypePugin is a stuct with callback
GO(g_type_get_qdata, pFLu)
GO(g_type_get_type_registration_serial, uFv)
diff --git a/src/wrapped/wrappedgomp.c b/src/wrapped/wrappedgomp.c
index 650da53..6cf9f20 100644
--- a/src/wrapped/wrappedgomp.c
+++ b/src/wrapped/wrappedgomp.c
@@ -6,13 +6,68 @@
#include "wrappedlibs.h"
+#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "gtkclass.h"
+#include "myalign.h"
const char* gompName = "libgomp.so.1";
#define LIBNAME gomp
+#define ADDED_FUNCTIONS() \
+
+#include "generated/wrappedgomptypes.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3) \
+
+// parallel
+#define GO(A) \
+static uintptr_t my_parallel_fct_##A = 0; \
+static void my_parallel_##A(void* a) \
+{ \
+ RunFunctionFmt(my_parallel_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* find_parallel_Fct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_parallel_fct_##A == (uintptr_t)fct) return my_parallel_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_parallel_fct_##A == 0) {my_parallel_fct_##A = (uintptr_t)fct; return my_parallel_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for libgomp Boxed parallel callback\n");
+ return NULL;
+}
+
+#undef SUPER
+
+EXPORT void my_GOMP_parallel(x64emu_t* emu, void* f, void* data, unsigned num_threads, uint32_t flags)
+{
+ my->GOMP_parallel(find_parallel_Fct(f), data, num_threads, flags);
+}
+
+#define CUSTOM_INIT \
+ getMy(lib); \
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgomp_private.h b/src/wrapped/wrappedgomp_private.h
index 33b1970..c7ccd76 100644
--- a/src/wrapped/wrappedgomp_private.h
+++ b/src/wrapped/wrappedgomp_private.h
@@ -220,7 +220,7 @@
//GO(GOMP_offload_unregister_ver,
//GO(GOMP_ordered_end,
//GO(GOMP_ordered_start,
-//GO(GOMP_parallel,
+GOM(GOMP_parallel, vFEppuu)
//GO(GOMP_parallel_end,
//GO(GOMP_parallel_loop_dynamic,
//GO(GOMP_parallel_loop_dynamic_start,
@@ -339,7 +339,7 @@
//GO(omp_get_max_task_priority_,
//GO(omp_get_max_teams,
//GO(omp_get_max_teams_,
-//GO(omp_get_max_threads,
+GO(omp_get_max_threads, iFv)
//GO(omp_get_max_threads_,
//GO(omp_get_nested,
//GO(omp_get_nested_,
@@ -351,7 +351,7 @@
//GO(omp_get_num_procs_,
//GO(omp_get_num_teams,
//GO(omp_get_num_teams_,
-//GO(omp_get_num_threads,
+GO(omp_get_num_threads, iFv)
//GO(omp_get_num_threads_,
//GO(omp_get_partition_num_places,
//GO(omp_get_partition_num_places_,
@@ -382,7 +382,7 @@
//GO(omp_get_teams_thread_limit_,
//GO(omp_get_thread_limit,
//GO(omp_get_thread_limit_,
-//GO(omp_get_thread_num,
+GO(omp_get_thread_num, iFv)
//GO(omp_get_thread_num_,
//GO(omp_get_wtick,
//GO(omp_get_wtick_,
diff --git a/src/wrapped/wrappedgssapikrb5_private.h b/src/wrapped/wrappedgssapikrb5_private.h
index fa57c6a..e95d77d 100644
--- a/src/wrapped/wrappedgssapikrb5_private.h
+++ b/src/wrapped/wrappedgssapikrb5_private.h
@@ -79,7 +79,7 @@ GO(gss_import_name, uFpppp)
//GO(gss_import_sec_context,
//GO(gss_indicate_mechs,
//GO(gss_indicate_mechs_by_attrs,
-GO(gss_init_sec_context, uFppppuuupppppp)
+GO(gss_init_sec_context, uFpppppuupppppp)
//GO(gss_inquire_attrs_for_mech,
GO(gss_inquire_context, uFppppppppp)
//GO(gss_inquire_cred,
@@ -90,7 +90,7 @@ GO(gss_inquire_context, uFppppppppp)
//GO(gss_inquire_name,
//GO(gss_inquire_names_for_mech,
//GO(gss_inquire_saslname_for_mech,
-//GO(gss_inquire_sec_context_by_oid,
+GO(gss_inquire_sec_context_by_oid, uFpppp)
//GO(gssint_g_seqstate_init,
//GO(gss_krb5_ccache_name,
//GO(gss_krb5_copy_ccache,
@@ -129,7 +129,7 @@ GO(gss_inquire_context, uFppppppppp)
//GO(gss_pseudo_random,
//GO(gss_release_any_name_mapping,
GO(gss_release_buffer, uFpp)
-//GO(gss_release_buffer_set,
+GO(gss_release_buffer_set, uFpp)
GO(gss_release_cred, uFpp)
GO(gss_release_iov_buffer, uFppi)
GO(gss_release_name, uFpp)
@@ -153,11 +153,11 @@ GO(gss_unwrap, uFpppppp)
GO(gss_unwrap_iov, uFpppppi)
//GO(gss_userok,
//GO(gss_verify,
-GO(gss_verify_mic, uFppppu)
+GO(gss_verify_mic, uFppppp)
//GO(gss_verify_mic_iov,
GO(gss_wrap, uFppiuppp)
//GO(gss_wrap_aead,
-GO(gss_wrap_iov, iFppiuppi)
+GO(gss_wrap_iov, uFppiuppi)
//GO(gss_wrap_iov_length,
//GO(gss_wrap_size_limit,
//DATAB(krb5_gss_dbg_client_expcreds,
diff --git a/src/wrapped/wrappedgstallocators.c b/src/wrapped/wrappedgstallocators.c
new file mode 100644
index 0000000..ebdcb0f
--- /dev/null
+++ b/src/wrapped/wrappedgstallocators.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstallocatorsName = "libgstallocators-1.0.so";
+#else
+ const char* gstallocatorsName = "libgstallocators-1.0.so.0";
+#endif
+
+#define LIBNAME gstallocators
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstallocators_private.h b/src/wrapped/wrappedgstallocators_private.h
new file mode 100644
index 0000000..18c71e1
--- /dev/null
+++ b/src/wrapped/wrappedgstallocators_private.h
@@ -0,0 +1,18 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(gst_dmabuf_allocator_alloc, pFpiL)
+//GO(gst_dmabuf_allocator_alloc_with_flags,
+GO(gst_dmabuf_allocator_get_type, LFv)
+GO(gst_dmabuf_allocator_new, pFv)
+//GO(gst_dmabuf_memory_get_fd,
+//GO(gst_fd_allocator_alloc,
+GO(gst_fd_allocator_get_type, LFv)
+//GO(gst_fd_allocator_new,
+//GO(gst_fd_memory_get_fd,
+//GO(gst_is_dmabuf_memory,
+//GO(gst_is_fd_memory,
+//GO(gst_is_phys_memory,
+GO(gst_phys_memory_allocator_get_type, LFv)
+//GO(gst_phys_memory_get_phys_addr, \ No newline at end of file
diff --git a/src/wrapped/wrappedgstapp.c b/src/wrapped/wrappedgstapp.c
index 92322f3..bc712f7 100644
--- a/src/wrapped/wrappedgstapp.c
+++ b/src/wrapped/wrappedgstapp.c
@@ -12,7 +12,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* gstappName = "libgstapp-1.0.so.0";
+#ifdef ANDROID
+ const char* gstappName = "libgstapp-1.0.so";
+#else
+ const char* gstappName = "libgstapp-1.0.so.0";
+#endif
+
#define LIBNAME gstapp
#define PRE_INIT \
diff --git a/src/wrapped/wrappedgstaudio.c b/src/wrapped/wrappedgstaudio.c
index 5f4e2a4..cde06e0 100644
--- a/src/wrapped/wrappedgstaudio.c
+++ b/src/wrapped/wrappedgstaudio.c
@@ -11,12 +11,49 @@
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+#include "gtkclass.h"
+#include "fileutils.h"
+
+#ifdef ANDROID
+ const char* gstaudioName = "libgstaudio-1.0.so";
+#else
+ const char* gstaudioName = "libgstaudio-1.0.so.0";
+#endif
-const char* gstaudioName = "libgstaudio-1.0.so.0";
#define LIBNAME gstaudio
+typedef size_t (*LFv_t)();
+
+#define ADDED_FUNCTIONS() \
+ GO(gst_audio_decoder_get_type, LFv_t) \
+
+#include "generated/wrappedgstaudiotypes.h"
+
+#include "wrappercallback.h"
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstAudioDecoderID(my->gst_audio_decoder_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstAudioDecoderID(my->gst_audio_decoder_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so.0");
+#endif
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstaudio_private.h b/src/wrapped/wrappedgstaudio_private.h
index ef7996c..f297ebf 100644
--- a/src/wrapped/wrappedgstaudio_private.h
+++ b/src/wrapped/wrappedgstaudio_private.h
@@ -50,7 +50,7 @@ GO(gst_audio_channel_positions_to_mask, iFpiip)
GO(gst_audio_channel_positions_to_string, pFpi)
GO(gst_audio_channel_positions_to_valid_order, iFpi)
GO(gst_audio_check_valid_channel_positions, iFpii)
-//GO(gst_audio_clipping_meta_api_get_type,
+GO(gst_audio_clipping_meta_api_get_type, LFv)
//GO(gst_audio_clipping_meta_get_info,
//GO(gst_audio_clock_adjust,
//GO(gst_audio_clock_get_time,
@@ -72,10 +72,10 @@ GO(gst_audio_converter_reset, vFp)
GO(gst_audio_converter_samples, iFpupLpL)
//GO(gst_audio_converter_supports_inplace,
GO(gst_audio_converter_update_config, iFpiip)
-//GO(gst_audio_decoder_allocate_output_buffer,
-//GO(_gst_audio_decoder_error,
-//GO(gst_audio_decoder_finish_frame,
-//GO(gst_audio_decoder_finish_subframe,
+GO(gst_audio_decoder_allocate_output_buffer, pFpL)
+GO(_gst_audio_decoder_error, iFpipippppi)
+GO(gst_audio_decoder_finish_frame, iFppi)
+GO(gst_audio_decoder_finish_subframe, iFpp)
//GO(gst_audio_decoder_get_allocator,
//GO(gst_audio_decoder_get_audio_info,
//GO(gst_audio_decoder_get_delay,
@@ -89,30 +89,30 @@ GO(gst_audio_converter_update_config, iFpiip)
//GO(gst_audio_decoder_get_plc,
//GO(gst_audio_decoder_get_plc_aware,
//GO(gst_audio_decoder_get_tolerance,
-//GO(gst_audio_decoder_get_type,
+GO(gst_audio_decoder_get_type, LFv)
//GO(gst_audio_decoder_merge_tags,
//GO(gst_audio_decoder_negotiate,
//GO(gst_audio_decoder_proxy_getcaps,
//GO(gst_audio_decoder_set_allocation_caps,
-//GO(gst_audio_decoder_set_drainable,
+GO(gst_audio_decoder_set_drainable, vFpi)
//GO(gst_audio_decoder_set_estimate_rate,
//GO(gst_audio_decoder_set_latency,
//GO(gst_audio_decoder_set_max_errors,
//GO(gst_audio_decoder_set_min_latency,
-//GO(gst_audio_decoder_set_needs_format,
+GO(gst_audio_decoder_set_needs_format, vFpi)
//GO(gst_audio_decoder_set_output_caps,
-//GO(gst_audio_decoder_set_output_format,
+GO(gst_audio_decoder_set_output_format, iFpp)
//GO(gst_audio_decoder_set_plc,
//GO(gst_audio_decoder_set_plc_aware,
//GO(gst_audio_decoder_set_tolerance,
-//GO(gst_audio_decoder_set_use_default_pad_acceptcaps,
+GO(gst_audio_decoder_set_use_default_pad_acceptcaps, vFpi)
//GO(gst_audio_dither_method_get_type,
//GO(gst_audio_downmix_meta_api_get_type,
//GO(gst_audio_downmix_meta_get_info,
//GO(gst_audio_encoder_allocate_output_buffer,
-//GO(gst_audio_encoder_finish_frame,
+GO(gst_audio_encoder_finish_frame, iFppi)
//GO(gst_audio_encoder_get_allocator,
-//GO(gst_audio_encoder_get_audio_info,
+GO(gst_audio_encoder_get_audio_info, pFp)
//GO(gst_audio_encoder_get_drainable,
//GO(gst_audio_encoder_get_frame_max,
//GO(gst_audio_encoder_get_frame_samples_max,
@@ -124,34 +124,35 @@ GO(gst_audio_converter_update_config, iFpiip)
//GO(gst_audio_encoder_get_mark_granule,
//GO(gst_audio_encoder_get_perfect_timestamp,
//GO(gst_audio_encoder_get_tolerance,
-//GO(gst_audio_encoder_get_type,
-//GO(gst_audio_encoder_merge_tags,
+GO(gst_audio_encoder_get_type, LFv)
+GO(gst_audio_encoder_merge_tags, vFppi)
//GO(gst_audio_encoder_negotiate,
//GO(gst_audio_encoder_proxy_getcaps,
//GO(gst_audio_encoder_set_allocation_caps,
-//GO(gst_audio_encoder_set_drainable,
-//GO(gst_audio_encoder_set_frame_max,
-//GO(gst_audio_encoder_set_frame_samples_max,
-//GO(gst_audio_encoder_set_frame_samples_min,
+GO(gst_audio_encoder_set_drainable, vFpi)
+GO(gst_audio_encoder_set_frame_max, vFpi)
+GO(gst_audio_encoder_set_frame_samples_max, vFpi)
+GO(gst_audio_encoder_set_frame_samples_min, vFpi)
//GO(gst_audio_encoder_set_hard_min,
//GO(gst_audio_encoder_set_hard_resync,
//GO(gst_audio_encoder_set_headers,
//GO(gst_audio_encoder_set_latency,
//GO(gst_audio_encoder_set_lookahead,
//GO(gst_audio_encoder_set_mark_granule,
-//GO(gst_audio_encoder_set_output_format,
+GO(gst_audio_encoder_set_output_format, iFpp)
//GO(gst_audio_encoder_set_perfect_timestamp,
//GO(gst_audio_encoder_set_tolerance,
//GO(gst_audio_filter_class_add_pad_templates,
//GO(gst_audio_filter_get_type,
//GO(gst_audio_flags_get_type,
GO(gst_audio_format_build_integer, uFiiii)
-//GO(gst_audio_format_fill_silence,
+GO(gst_audio_format_fill_silence, vFppL)
//GO(gst_audio_format_flags_get_type,
GO(gst_audio_format_from_string, uFp)
//GO(gst_audio_format_get_info,
//GO(gst_audio_format_get_type,
-//GO(gst_audio_format_info_get_type,
+GO(gst_audio_format_info_fill_silence, vFppL)
+GO(gst_audio_format_info_get_type, LFv)
GO(gst_audio_formats_raw, pFp)
GO(gst_audio_format_to_string, pFu)
GO(gst_audio_get_channel_reorder_map, iFippp)
@@ -244,7 +245,7 @@ GO(gst_audio_stream_align_set_discont_wait, vFpL)
GO(gst_audio_stream_align_set_rate, vFpi)
GO(gst_buffer_add_audio_clipping_meta, pFpuLL)
GO(gst_buffer_add_audio_downmix_meta, pFppipip)
-//GO(gst_buffer_add_audio_meta,
+GO(gst_buffer_add_audio_meta, pFppLp)
GO(gst_buffer_get_audio_downmix_meta_for_channels, pFppi)
GO(gst_stream_volume_convert_volume, dFuud)
GO(gst_stream_volume_get_mute, iFp)
diff --git a/src/wrapped/wrappedgstbase.c b/src/wrapped/wrappedgstbase.c
index 266ef86..495357d 100644
--- a/src/wrapped/wrappedgstbase.c
+++ b/src/wrapped/wrappedgstbase.c
@@ -11,12 +11,247 @@
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+#include "gtkclass.h"
+#include "fileutils.h"
+
+#ifdef ANDROID
+ const char* gstbaseName = "libgstbase-1.0.so";
+#else
+ const char* gstbaseName = "libgstbase-1.0.so.0";
+#endif
-const char* gstbaseName = "libgstbase-1.0.so.0";
#define LIBNAME gstbase
+typedef size_t (*LFv_t)();
+
+#define ADDED_FUNCTIONS() \
+ GO(gst_base_transform_get_type, LFv_t) \
+ GO(gst_base_sink_get_type, LFv_t) \
+ GO(gst_aggregator_get_type, LFv_t) \
+ GO(gst_push_src_get_type, LFv_t) \
+ GO(gst_base_src_get_type, LFv_t) \
+ GO(gst_aggregator_pad_get_type, LFv_t) \
+
+#include "generated/wrappedgstbasetypes.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3)
+
+// GstCollectPadsFunction ...
+#define GO(A) \
+static uintptr_t my_GstCollectPadsFunction_fct_##A = 0; \
+static int my_GstCollectPadsFunction_##A(void* a, void* b) \
+{ \
+ return RunFunctionFmt(my_GstCollectPadsFunction_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectPadsFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectPadsFunction_fct_##A == (uintptr_t)fct) return my_GstCollectPadsFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectPadsFunction_fct_##A == 0) {my_GstCollectPadsFunction_fct_##A = (uintptr_t)fct; return my_GstCollectPadsFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectPadsFunction callback\n");
+ return NULL;
+}
+// GstCollectDataDestroyNotify ...
+#define GO(A) \
+static uintptr_t my_GstCollectDataDestroyNotify_fct_##A = 0; \
+static void my_GstCollectDataDestroyNotify_##A(void* a) \
+{ \
+ RunFunctionFmt(my_GstCollectDataDestroyNotify_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectDataDestroyNotifyFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectDataDestroyNotify_fct_##A == (uintptr_t)fct) return my_GstCollectDataDestroyNotify_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectDataDestroyNotify_fct_##A == 0) {my_GstCollectDataDestroyNotify_fct_##A = (uintptr_t)fct; return my_GstCollectDataDestroyNotify_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectDataDestroyNotify callback\n");
+ return NULL;
+}
+// GstCollectPadsEventFunction ...
+#define GO(A) \
+static uintptr_t my_GstCollectPadsEventFunction_fct_##A = 0; \
+static int my_GstCollectPadsEventFunction_##A(void* a, void* b, void* c, void* d) \
+{ \
+ return RunFunctionFmt(my_GstCollectPadsEventFunction_fct_##A, "pppp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectPadsEventFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectPadsEventFunction_fct_##A == (uintptr_t)fct) return my_GstCollectPadsEventFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectPadsEventFunction_fct_##A == 0) {my_GstCollectPadsEventFunction_fct_##A = (uintptr_t)fct; return my_GstCollectPadsEventFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectPadsEventFunction callback\n");
+ return NULL;
+}
+// GstCollectPadsQueryFunction ...
+#define GO(A) \
+static uintptr_t my_GstCollectPadsQueryFunction_fct_##A = 0; \
+static int my_GstCollectPadsQueryFunction_##A(void* a, void* b, void* c, void* d) \
+{ \
+ return RunFunctionFmt(my_GstCollectPadsQueryFunction_fct_##A, "pppp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectPadsQueryFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectPadsQueryFunction_fct_##A == (uintptr_t)fct) return my_GstCollectPadsQueryFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectPadsQueryFunction_fct_##A == 0) {my_GstCollectPadsQueryFunction_fct_##A = (uintptr_t)fct; return my_GstCollectPadsQueryFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectPadsQueryFunction callback\n");
+ return NULL;
+}
+// GstCollectPadsClipFunction ...
+#define GO(A) \
+static uintptr_t my_GstCollectPadsClipFunction_fct_##A = 0; \
+static int my_GstCollectPadsClipFunction_##A(void* a, void* b, void* c, void* d, void* e) \
+{ \
+ return RunFunctionFmt(my_GstCollectPadsClipFunction_fct_##A, "ppppp", a, b, c, d, e); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectPadsClipFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectPadsClipFunction_fct_##A == (uintptr_t)fct) return my_GstCollectPadsClipFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectPadsClipFunction_fct_##A == 0) {my_GstCollectPadsClipFunction_fct_##A = (uintptr_t)fct; return my_GstCollectPadsClipFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectPadsClipFunction callback\n");
+ return NULL;
+}
+// GstCollectPadsBufferFunction ...
+#define GO(A) \
+static uintptr_t my_GstCollectPadsBufferFunction_fct_##A = 0; \
+static int my_GstCollectPadsBufferFunction_##A(void* a, void* b, void* c, void* d) \
+{ \
+ return RunFunctionFmt(my_GstCollectPadsBufferFunction_fct_##A, "pppp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* findGstCollectPadsBufferFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_GstCollectPadsBufferFunction_fct_##A == (uintptr_t)fct) return my_GstCollectPadsBufferFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstCollectPadsBufferFunction_fct_##A == 0) {my_GstCollectPadsBufferFunction_fct_##A = (uintptr_t)fct; return my_GstCollectPadsBufferFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstbase GstCollectPadsBufferFunction callback\n");
+ return NULL;
+}
+
+#undef SUPER
+
+EXPORT void my_gst_collect_pads_set_function(x64emu_t* emu, void* p, void* f, void* data)
+{
+ my->gst_collect_pads_set_function(p, findGstCollectPadsFunctionFct(f), data);
+}
+
+EXPORT void* my_gst_collect_pads_add_pad(x64emu_t* emu, void* pads, void* pad, uint32_t size, void* d, int lock)
+{
+ return my->gst_collect_pads_add_pad(pads, pad, size, findGstCollectDataDestroyNotifyFct(d), lock);
+}
+
+EXPORT void my_gst_collect_pads_set_event_function(x64emu_t* emu, void* pads, void* f, void* data)
+{
+ my->gst_collect_pads_set_event_function(pads, findGstCollectPadsEventFunctionFct(f), data);
+}
+
+EXPORT void my_gst_collect_pads_set_query_function(x64emu_t* emu, void* pads, void* f, void* data)
+{
+ my->gst_collect_pads_set_query_function(pads, findGstCollectPadsQueryFunctionFct(f), data);
+}
+
+EXPORT void my_gst_collect_pads_set_clip_function(x64emu_t* emu, void* pads, void* f, void* data)
+{
+ my->gst_collect_pads_set_clip_function(pads, findGstCollectPadsClipFunctionFct(f), data);
+}
+
+EXPORT void my_gst_collect_pads_set_buffer_function(x64emu_t* emu, void* pads, void* f, void* data)
+{
+ my->gst_collect_pads_set_buffer_function(pads, findGstCollectPadsBufferFunctionFct(f), data);
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstBaseTransformID(my->gst_base_transform_get_type());\
+ SetGstBaseSinkID(my->gst_base_sink_get_type());\
+ SetGstAggregatorID(my->gst_aggregator_get_type());\
+ SetGstPushSrcID(my->gst_push_src_get_type());\
+ SetGstBaseSrcID(my->gst_base_src_get_type());\
+ SetGstAggregatorPadID(my->gst_aggregator_pad_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstBaseTransformID(my->gst_base_transform_get_type());\
+ SetGstBaseSinkID(my->gst_base_sink_get_type());\
+ SetGstAggregatorID(my->gst_aggregator_get_type());\
+ SetGstPushSrcID(my->gst_push_src_get_type());\
+ SetGstBaseSrcID(my->gst_base_src_get_type());\
+ SetGstAggregatorPadID(my->gst_aggregator_pad_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so.0");
+#endif
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstbase_private.h b/src/wrapped/wrappedgstbase_private.h
index f203a1b..68b5242 100644
--- a/src/wrapped/wrappedgstbase_private.h
+++ b/src/wrapped/wrappedgstbase_private.h
@@ -2,9 +2,9 @@
#error meh!
#endif
-//GO(gst_adapter_available,
+GO(gst_adapter_available, LFp)
GO(gst_adapter_available_fast, LFp)
-//GO(gst_adapter_clear,
+GO(gst_adapter_clear, vFp)
GO(gst_adapter_copy, vFppLL)
GO(gst_adapter_copy_bytes, pFpLL)
GO(gst_adapter_distance_from_discont, LFp)
@@ -14,7 +14,7 @@ GO(gst_adapter_flush, vFpL)
GO(gst_adapter_get_buffer_fast, pFpL)
GO(gst_adapter_get_buffer_list, pFpL)
GO(gst_adapter_get_list, pFpL)
-//GO(gst_adapter_get_type,
+GO(gst_adapter_get_type, LFv)
GO(gst_adapter_map, pFpL)
GO(gst_adapter_masked_scan_uint32, lFpuuLL)
GO(gst_adapter_masked_scan_uint32_peek, lFpuuLLp)
@@ -28,20 +28,20 @@ GO(gst_adapter_prev_offset, LFpp)
//GO(gst_adapter_pts_at_discont,
GO(gst_adapter_push, vFpp)
GO(gst_adapter_take, pFpL)
-//GO(gst_adapter_take_buffer,
+GO(gst_adapter_take_buffer, pFpL)
//GO(gst_adapter_take_buffer_fast,
//GO(gst_adapter_take_buffer_list,
//GO(gst_adapter_take_list,
-//GO(gst_adapter_unmap,
-//GO(gst_aggregator_finish_buffer,
+GO(gst_adapter_unmap, vFp)
+GO(gst_aggregator_finish_buffer, iFpp)
//GO(gst_aggregator_finish_buffer_list,
//GO(gst_aggregator_get_allocator,
//GO(gst_aggregator_get_buffer_pool,
//GO(gst_aggregator_get_latency,
-//GO(gst_aggregator_get_type,
+GO(gst_aggregator_get_type, LFv)
//GO(gst_aggregator_negotiate,
//GO(gst_aggregator_pad_drop_buffer,
-//GO(gst_aggregator_pad_get_type,
+GO(gst_aggregator_pad_get_type, LFv)
//GO(gst_aggregator_pad_has_buffer,
//GO(gst_aggregator_pad_is_eos,
//GO(gst_aggregator_pad_peek_buffer,
@@ -89,7 +89,7 @@ GO(gst_adapter_take, pFpL)
//GO(gst_base_sink_get_sync,
//GO(gst_base_sink_get_throttle_time,
//GO(gst_base_sink_get_ts_offset,
-//GO(gst_base_sink_get_type,
+GO(gst_base_sink_get_type, LFv)
//GO(gst_base_sink_is_async_enabled,
//GO(gst_base_sink_is_last_sample_enabled,
//GO(gst_base_sink_is_qos_enabled,
@@ -110,44 +110,44 @@ GO(gst_adapter_take, pFpL)
//GO(gst_base_sink_wait_clock,
//GO(gst_base_sink_wait_preroll,
//GO(gst_base_src_get_allocator,
-//GO(gst_base_src_get_blocksize,
+GO(gst_base_src_get_blocksize, uFp)
//GO(gst_base_src_get_buffer_pool,
//GO(gst_base_src_get_do_timestamp,
-//GO(gst_base_src_get_type,
+GO(gst_base_src_get_type, LFv)
//GO(gst_base_src_is_async,
-//GO(gst_base_src_is_live,
+GO(gst_base_src_is_live, iFp)
//GO(gst_base_src_negotiate,
//GO(gst_base_src_new_seamless_segment,
//GO(gst_base_src_new_segment,
//GO(gst_base_src_query_latency,
//GO(gst_base_src_set_async,
-//GO(gst_base_src_set_automatic_eos,
-//GO(gst_base_src_set_blocksize,
-//GO(gst_base_src_set_caps,
+GO(gst_base_src_set_automatic_eos, vFpi)
+GO(gst_base_src_set_blocksize, vFpu)
+GO(gst_base_src_set_caps, iFpp)
//GO(gst_base_src_set_do_timestamp,
//GO(gst_base_src_set_dynamic_size,
//GO(gst_base_src_set_format,
-//GO(gst_base_src_set_live,
+GO(gst_base_src_set_live, vFpi)
//GO(gst_base_src_start_complete,
//GO(gst_base_src_start_wait,
//GO(gst_base_src_submit_buffer_list,
//GO(gst_base_src_wait_playing,
//GO(gst_base_transform_get_allocator,
//GO(gst_base_transform_get_buffer_pool,
-//GO(gst_base_transform_get_type,
+GO(gst_base_transform_get_type, LFv)
//GO(gst_base_transform_is_in_place,
-//GO(gst_base_transform_is_passthrough,
+GO(gst_base_transform_is_passthrough, iFp)
//GO(gst_base_transform_is_qos_enabled,
//GO(gst_base_transform_reconfigure,
//GO(gst_base_transform_reconfigure_sink,
-//GO(gst_base_transform_reconfigure_src,
-//GO(gst_base_transform_set_gap_aware,
-//GO(gst_base_transform_set_in_place,
-//GO(gst_base_transform_set_passthrough,
-//GO(gst_base_transform_set_prefer_passthrough,
+GO(gst_base_transform_reconfigure_src, vFp)
+GO(gst_base_transform_set_gap_aware, vFpi)
+GO(gst_base_transform_set_in_place, vFpi)
+GO(gst_base_transform_set_passthrough, vFpi)
+GO(gst_base_transform_set_prefer_passthrough, vFpi)
//GO(gst_base_transform_set_qos_enabled,
//GO(gst_base_transform_update_qos,
-//GO(gst_base_transform_update_src_caps,
+GO(gst_base_transform_update_src_caps, iFpp)
//GO(gst_bit_reader_free,
//GO(gst_bit_reader_get_bits_uint16,
//GO(gst_bit_reader_get_bits_uint32,
@@ -248,18 +248,18 @@ GO(gst_byte_reader_peek_string_utf8, iFpp)
//GO(gst_byte_reader_peek_uint64_be,
//GO(gst_byte_reader_peek_uint64_le,
//GO(gst_byte_reader_peek_uint8,
-//GO(gst_byte_reader_set_pos,
+GO(gst_byte_reader_set_pos, iFpu)
//GO(gst_byte_reader_skip,
//GO(gst_byte_reader_skip_string_utf16,
GO(gst_byte_reader_skip_string_utf32, iFp)
//GO(gst_byte_reader_skip_string_utf8,
//GO(gst_byte_writer_ensure_free_space,
//GO(gst_byte_writer_fill,
-//GO(gst_byte_writer_free,
-//GO(gst_byte_writer_free_and_get_buffer,
+GO(gst_byte_writer_free, vFp)
+GO(gst_byte_writer_free_and_get_buffer, pFp)
//GO(gst_byte_writer_free_and_get_data,
GO(gst_byte_writer_get_remaining, uFp)
-//GO(gst_byte_writer_init,
+GO(gst_byte_writer_init, vFp)
GO(gst_byte_writer_init_with_data, vFppui)
GO(gst_byte_writer_init_with_size, vFpui)
GO(gst_byte_writer_new, pFv)
@@ -294,31 +294,31 @@ GO(gst_byte_writer_put_string_utf8, iFpp)
GO(gst_byte_writer_reset, vFp)
GO(gst_byte_writer_reset_and_get_buffer, pFp)
GO(gst_byte_writer_reset_and_get_data, pFp)
-//GO(gst_collect_pads_add_pad,
+GOM(gst_collect_pads_add_pad, pFEppupi)
GO(gst_collect_pads_available, uFp)
-//GO(gst_collect_pads_clip_running_time,
-//GO(gst_collect_pads_event_default,
+GO(gst_collect_pads_clip_running_time, iFppppp)
+GO(gst_collect_pads_event_default, iFpppi)
//GO(gst_collect_pads_flush,
//GO(gst_collect_pads_get_type,
GO(gst_collect_pads_new, pFv)
-//GO(gst_collect_pads_peek,
-//GO(gst_collect_pads_pop,
-//GO(gst_collect_pads_query_default,
+GO(gst_collect_pads_peek, pFpp)
+GO(gst_collect_pads_pop, pFpp)
+GO(gst_collect_pads_query_default, iFpppi)
//GO(gst_collect_pads_read_buffer,
-//GO(gst_collect_pads_remove_pad,
-//GO(gst_collect_pads_set_buffer_function,
-//GO(gst_collect_pads_set_clip_function,
+GO(gst_collect_pads_remove_pad, iFpp)
+GOM(gst_collect_pads_set_buffer_function, vFEppp)
+GOM(gst_collect_pads_set_clip_function, vFEppp)
//GO(gst_collect_pads_set_compare_function,
-//GO(gst_collect_pads_set_event_function,
+GOM(gst_collect_pads_set_event_function, vFEppp)
//GO(gst_collect_pads_set_flush_function,
GO(gst_collect_pads_set_flushing, vFpi)
-//GO(gst_collect_pads_set_function,
-//GO(gst_collect_pads_set_query_function,
-//GO(gst_collect_pads_set_waiting,
+GOM(gst_collect_pads_set_function, vFEppp)
+GOM(gst_collect_pads_set_query_function, vFEppp)
+GO(gst_collect_pads_set_waiting, vFppi)
//GO(gst_collect_pads_src_event_default,
-//GO(gst_collect_pads_start,
-//GO(gst_collect_pads_stop,
-//GO(gst_collect_pads_take_buffer,
+GO(gst_collect_pads_start, vFp)
+GO(gst_collect_pads_stop, vFp)
+GO(gst_collect_pads_take_buffer, pFppu)
GO(gst_data_queue_drop_head, iFpL)
//GO(gst_data_queue_flush,
GO(gst_data_queue_get_level, vFpp)
@@ -332,17 +332,17 @@ GO(gst_data_queue_peek, iFpp)
//GO(gst_data_queue_push,
//GO(gst_data_queue_push_force,
GO(gst_data_queue_set_flushing, vFpi)
-//GO(gst_flow_combiner_add_pad,
-//GO(gst_flow_combiner_clear,
-//GO(gst_flow_combiner_free,
-//GO(gst_flow_combiner_get_type,
+GO(gst_flow_combiner_add_pad, vFpp)
+GO(gst_flow_combiner_clear, vFp)
+GO(gst_flow_combiner_free, vFp)
+GO(gst_flow_combiner_get_type, LFv)
GO(gst_flow_combiner_new, pFv)
GO(gst_flow_combiner_ref, pFp)
-//GO(gst_flow_combiner_remove_pad,
-//GO(gst_flow_combiner_reset,
+GO(gst_flow_combiner_remove_pad, vFpp)
+GO(gst_flow_combiner_reset, vFp)
//GO(gst_flow_combiner_unref,
GO(gst_flow_combiner_update_flow, iFpi)
-//GO(gst_flow_combiner_update_pad_flow,
+GO(gst_flow_combiner_update_pad_flow, iFppi)
GO(gst_push_src_get_type, LFv)
GO(gst_queue_array_clear, vFp)
//GO(gst_queue_array_drop_element,
@@ -367,7 +367,7 @@ GO(gst_queue_array_peek_tail_struct, pFp)
GO(gst_queue_array_push_tail_struct, vFpp)
//GO(gst_queue_array_set_clear_func,
//GO(gst_type_find_helper,
-//GO(gst_type_find_helper_for_buffer,
+GO(gst_type_find_helper_for_buffer, pFppp)
//GO(gst_type_find_helper_for_buffer_with_extension,
//GO(gst_type_find_helper_for_data,
GO(gst_type_find_helper_for_data_with_extension, pFppLpp)
diff --git a/src/wrapped/wrappedgstcheck.c b/src/wrapped/wrappedgstcheck.c
new file mode 100644
index 0000000..e52bf0b
--- /dev/null
+++ b/src/wrapped/wrappedgstcheck.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstcheckName = "libgstcheck-1.0.so";
+#else
+ const char* gstcheckName = "libgstcheck-1.0.so.0";
+#endif
+
+#define LIBNAME gstcheck
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstcheck_private.h b/src/wrapped/wrappedgstcheck_private.h
new file mode 100644
index 0000000..b2f2bfc
--- /dev/null
+++ b/src/wrapped/wrappedgstcheck_private.h
@@ -0,0 +1,203 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+//DATAB(buffers,
+//DATAB(check_cond,
+//DATAB(check_debug,
+//GO(check_fork,
+//DATAB(check_major_version,
+//DATA(check_micro_version,
+//DATA(check_minor_version,
+//DATAB(check_mutex,
+//GO(check_waitpid_and_exit,
+//GO(_ck_assert_failed,
+//GO(_fail_unless,
+//GO(gst_buffer_straw_get_buffer,
+//GO(gst_buffer_straw_start_pipeline,
+//GO(gst_buffer_straw_stop_pipeline,
+//GO(gst_check_abi_list,
+//GO(gst_check_add_log_filter,
+//GO(gst_check_buffer_data,
+//GO(gst_check_caps_equal,
+//GO(gst_check_chain_func,
+//GO(gst_check_clear_log_filter,
+//GO(gst_check_drop_buffers,
+//GO(gst_check_element_push_buffer,
+//GO(gst_check_element_push_buffer_list,
+//DATAB(_gst_check_expecting_log,
+//GO(gst_check_init,
+//DATAB(_gst_check_list_tests,
+//GO(gst_check_message_error,
+//GO(gst_check_object_destroyed_on_unref,
+//GO(gst_check_objects_destroyed_on_unref,
+//DATAB(_gst_check_raised_critical,
+//DATAB(_gst_check_raised_warning,
+//GO(gst_check_remove_log_filter,
+//GO(gst_check_run_suite,
+//GO(_gst_check_run_test_func,
+//GO(gst_check_setup_element,
+//GO(gst_check_setup_events,
+//GO(gst_check_setup_events_with_stream_id,
+//GO(gst_check_setup_sink_pad,
+//GO(gst_check_setup_sink_pad_by_name,
+//GO(gst_check_setup_sink_pad_by_name_from_template,
+//GO(gst_check_setup_sink_pad_from_template,
+//GO(gst_check_setup_src_pad,
+//GO(gst_check_setup_src_pad_by_name,
+//GO(gst_check_setup_src_pad_by_name_from_template,
+//GO(gst_check_setup_src_pad_from_template,
+//GO(gst_check_teardown_element,
+//GO(gst_check_teardown_pad_by_name,
+//GO(gst_check_teardown_sink_pad,
+//GO(gst_check_teardown_src_pad,
+//DATAB(_gst_check_threads_running,
+//GO(gst_consistency_checker_add_pad,
+//GO(gst_consistency_checker_free,
+//GO(gst_consistency_checker_new,
+//GO(gst_consistency_checker_reset,
+//GO(gst_harness_add_element_full,
+//GO(gst_harness_add_element_sink_pad,
+//GO(gst_harness_add_element_src_pad,
+//GO(gst_harness_add_parse,
+//GO(gst_harness_add_probe,
+//GO(gst_harness_add_propose_allocation_meta,
+//GO(gst_harness_add_sink,
+//GO(gst_harness_add_sink_harness,
+//GO(gst_harness_add_sink_parse,
+//GO(gst_harness_add_src,
+//GO(gst_harness_add_src_harness,
+//GO(gst_harness_add_src_parse,
+//GO(gst_harness_buffers_in_queue,
+//GO(gst_harness_buffers_received,
+//GO(gst_harness_crank_multiple_clock_waits,
+//GO(gst_harness_crank_single_clock_wait,
+//GO(gst_harness_create_buffer,
+//GO(gst_harness_dump_to_file,
+//GO(gst_harness_events_in_queue,
+//GO(gst_harness_events_received,
+//GO(gst_harness_find_element,
+//GO(gst_harness_get,
+//GO(gst_harness_get_allocator,
+//GO(gst_harness_get_last_pushed_timestamp,
+//GO(gst_harness_get_testclock,
+//GO(gst_harness_new,
+//GO(gst_harness_new_empty,
+//GO(gst_harness_new_full,
+//GO(gst_harness_new_parse,
+//GO(gst_harness_new_with_element,
+//GO(gst_harness_new_with_padnames,
+//GO(gst_harness_new_with_templates,
+//GO(gst_harness_play,
+//GO(gst_harness_pull,
+//GO(gst_harness_pull_event,
+//GO(gst_harness_pull_until_eos,
+//GO(gst_harness_pull_upstream_event,
+//GO(gst_harness_push,
+//GO(gst_harness_push_and_pull,
+//GO(gst_harness_push_event,
+//GO(gst_harness_push_from_src,
+//GO(gst_harness_push_to_sink,
+//GO(gst_harness_push_upstream_event,
+//GO(gst_harness_query_latency,
+//GO(gst_harness_set,
+//GO(gst_harness_set_blocking_push_mode,
+//GO(gst_harness_set_caps,
+//GO(gst_harness_set_caps_str,
+//GO(gst_harness_set_drop_buffers,
+//GO(gst_harness_set_forwarding,
+//GO(gst_harness_set_live,
+//GO(gst_harness_set_propose_allocator,
+//GO(gst_harness_set_sink_caps,
+//GO(gst_harness_set_sink_caps_str,
+//GO(gst_harness_set_src_caps,
+//GO(gst_harness_set_src_caps_str,
+//GO(gst_harness_set_time,
+//GO(gst_harness_set_upstream_latency,
+//GO(gst_harness_sink_push_many,
+//GO(gst_harness_src_crank_and_push_many,
+//GO(gst_harness_src_push_event,
+//GO(gst_harness_stress_custom_start,
+//GO(gst_harness_stress_property_start_full,
+//GO(gst_harness_stress_push_buffer_start_full,
+//GO(gst_harness_stress_push_buffer_with_cb_start_full,
+//GO(gst_harness_stress_push_event_start_full,
+//GO(gst_harness_stress_push_event_with_cb_start_full,
+//GO(gst_harness_stress_push_upstream_event_start_full,
+//GO(gst_harness_stress_push_upstream_event_with_cb_start_full,
+//GO(gst_harness_stress_requestpad_start_full,
+//GO(gst_harness_stress_statechange_start_full,
+//GO(gst_harness_stress_thread_stop,
+//GO(gst_harness_take_all_data,
+//GO(gst_harness_take_all_data_as_buffer,
+//GO(gst_harness_take_all_data_as_bytes,
+//GO(gst_harness_teardown,
+//GO(gst_harness_try_pull,
+//GO(gst_harness_try_pull_event,
+//GO(gst_harness_try_pull_upstream_event,
+//GO(gst_harness_upstream_events_in_queue,
+//GO(gst_harness_upstream_events_received,
+//GO(gst_harness_use_systemclock,
+//GO(gst_harness_use_testclock,
+//GO(gst_harness_wait_for_clock_id_waits,
+//GO(gst_test_clock_advance_time,
+//GO(gst_test_clock_crank,
+//GO(gst_test_clock_get_next_entry_time,
+GO(gst_test_clock_get_type, LFv)
+//GO(gst_test_clock_has_id,
+//GO(gst_test_clock_id_list_get_latest_time,
+//GO(gst_test_clock_new,
+//GO(gst_test_clock_new_with_start_time,
+//GO(gst_test_clock_peek_id_count,
+//GO(gst_test_clock_peek_next_pending_id,
+//GO(gst_test_clock_process_id,
+//GO(gst_test_clock_process_id_list,
+//GO(gst_test_clock_process_next_clock_id,
+//GO(gst_test_clock_set_time,
+//GO(gst_test_clock_timed_wait_for_multiple_pending_ids,
+//GO(gst_test_clock_wait_for_multiple_pending_ids,
+//GO(gst_test_clock_wait_for_next_pending_id,
+//GO(gst_test_clock_wait_for_pending_id_count,
+//GO(_mark_point,
+//DATAB(mutex,
+//GO(srunner_add_suite,
+//GO(srunner_create,
+//GO(srunner_failures,
+//GO(srunner_fork_status,
+//GO(srunner_free,
+//GO(srunner_has_log,
+//GO(srunner_has_tap,
+//GO(srunner_has_xml,
+//GO(srunner_log_fname,
+//GO(srunner_ntests_failed,
+//GO(srunner_ntests_run,
+//GO(srunner_print,
+//GO(srunner_results,
+//GO(srunner_run,
+//GO(srunner_run_all,
+//GO(srunner_run_tagged,
+//GO(srunner_set_fork_status,
+//GO(srunner_set_log,
+//GO(srunner_set_tap,
+//GO(srunner_set_xml,
+//GO(srunner_tap_fname,
+//GO(srunner_xml_fname,
+//DATAB(start_cond,
+//GO(suite_add_tcase,
+//GO(suite_create,
+//GO(suite_tcase,
+//DATAB(sync_cond,
+//GO(tcase_add_checked_fixture,
+//GO(_tcase_add_test,
+//GO(tcase_add_unchecked_fixture,
+//GO(tcase_create,
+//GO(tcase_fn_start,
+//GO(tcase_set_tags,
+//GO(tcase_set_timeout,
+//DATAB(thread_list,
+//GO(tr_ctx,
+//GO(tr_lfile,
+//GO(tr_lno,
+//GO(tr_msg,
+//GO(tr_rtype,
+//GO(tr_tcname,
diff --git a/src/wrapped/wrappedgstcontroller.c b/src/wrapped/wrappedgstcontroller.c
new file mode 100644
index 0000000..c2a7cfc
--- /dev/null
+++ b/src/wrapped/wrappedgstcontroller.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstcontrollerName = "libgstcontroller-1.0.so";
+#else
+ const char* gstcontrollerName = "libgstcontroller-1.0.so.0";
+#endif
+
+#define LIBNAME gstcontroller
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstcontroller_private.h b/src/wrapped/wrappedgstcontroller_private.h
new file mode 100644
index 0000000..0cbde97
--- /dev/null
+++ b/src/wrapped/wrappedgstcontroller_private.h
@@ -0,0 +1,31 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(gst_argb_control_binding_get_type, LFv)
+//GO(gst_argb_control_binding_new,
+//GO(gst_control_point_copy,
+//GO(gst_control_point_free,
+GO(gst_control_point_get_type, LFv)
+GO(gst_direct_control_binding_get_type, LFv)
+//GO(gst_direct_control_binding_new,
+//GO(gst_direct_control_binding_new_absolute,
+GO(gst_interpolation_control_source_get_type, LFv)
+//GO(gst_interpolation_control_source_new,
+GO(gst_interpolation_mode_get_type, LFv)
+GO(gst_lfo_control_source_get_type, LFv)
+//GO(gst_lfo_control_source_new,
+GO(gst_lfo_waveform_get_type, LFv)
+GO(gst_proxy_control_binding_get_type, LFv)
+GO(gst_proxy_control_binding_new, pFpppp)
+//GO(gst_timed_value_control_invalidate_cache,
+//GO(gst_timed_value_control_source_find_control_point_iter,
+//GO(gst_timed_value_control_source_get_all,
+//GO(gst_timed_value_control_source_get_count,
+GO(gst_timed_value_control_source_get_type, LFv)
+//GO(gst_timed_value_control_source_set,
+//GO(gst_timed_value_control_source_set_from_list,
+//GO(gst_timed_value_control_source_unset,
+//GO(gst_timed_value_control_source_unset_all,
+GO(gst_trigger_control_source_get_type, LFv)
+//GO(gst_trigger_control_source_new,
diff --git a/src/wrapped/wrappedgstfft.c b/src/wrapped/wrappedgstfft.c
new file mode 100644
index 0000000..ee3a565
--- /dev/null
+++ b/src/wrapped/wrappedgstfft.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstfftName = "libgstfft-1.0.so";
+#else
+ const char* gstfftName = "libgstfft-1.0.so.0";
+#endif
+
+#define LIBNAME gstfft
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstfft_private.h b/src/wrapped/wrappedgstfft_private.h
new file mode 100644
index 0000000..6493423
--- /dev/null
+++ b/src/wrapped/wrappedgstfft_private.h
@@ -0,0 +1,25 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+//GO(gst_fft_f32_fft,
+//GO(gst_fft_f32_free,
+//GO(gst_fft_f32_inverse_fft,
+//GO(gst_fft_f32_new,
+//GO(gst_fft_f32_window,
+//GO(gst_fft_f64_fft,
+//GO(gst_fft_f64_free,
+//GO(gst_fft_f64_inverse_fft,
+//GO(gst_fft_f64_new,
+//GO(gst_fft_f64_window,
+//GO(gst_fft_next_fast_length,
+//GO(gst_fft_s16_fft,
+//GO(gst_fft_s16_free,
+//GO(gst_fft_s16_inverse_fft,
+//GO(gst_fft_s16_new,
+//GO(gst_fft_s16_window,
+//GO(gst_fft_s32_fft,
+//GO(gst_fft_s32_free,
+//GO(gst_fft_s32_inverse_fft,
+//GO(gst_fft_s32_new,
+//GO(gst_fft_s32_window,
diff --git a/src/wrapped/wrappedgstgl.c b/src/wrapped/wrappedgstgl.c
index bc23c29..fd82eda 100644
--- a/src/wrapped/wrappedgstgl.c
+++ b/src/wrapped/wrappedgstgl.c
@@ -1,7 +1,7 @@
+#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include "wrappedlibs.h"
@@ -11,12 +11,274 @@
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+#include "gtkclass.h"
+#include "fileutils.h"
+#include "gltools.h"
+
+#ifdef ANDROID
+ const char* gstglName = "libgstgl-1.0.so";
+#else
+ const char* gstglName = "libgstgl-1.0.so.0";
+#endif
-const char* gstglName = "libgstgl-1.0.so.0";
#define LIBNAME gstgl
+typedef size_t (*LFv_t)();
+
+#define ADDED_FUNCTIONS() \
+ GO(gst_gl_base_filter_get_type, LFv_t) \
+ GO(gst_gl_filter_get_type, LFv_t) \
+ GO(gst_gl_base_src_get_type, LFv_t) \
+
+#include "generated/wrappedgstgltypes.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3) \
+GO(4) \
+
+// getprocaddress_with_platform ...
+#define GO(A) \
+static uint64_t my_getprocaddress_platform_##A = 0; \
+static void* my_getprocaddress_with_platform_##A(const char* name) \
+{ \
+ int type = my_getprocaddress_platform_##A >> 32; \
+ int api = my_getprocaddress_platform_##A & 0xffffffff; \
+ return my->gst_gl_context_get_proc_address_with_platform(type, api, (void*)name); \
+}
+SUPER()
+#undef GO
+static glprocaddress_t findGetProcAddressPlatformFct(int type, int gl_api)
+{
+ uint64_t key = (((uint64_t)type)<<32) | (gl_api);
+ #define GO(A) if(my_getprocaddress_platform_##A == key) return my_getprocaddress_with_platform_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_getprocaddress_platform_##A == 0) {my_getprocaddress_platform_##A = key; return my_getprocaddress_with_platform_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl gst_gl_context_get_proc_address_with_platform callback\n");
+ return NULL;
+}
+
+// getprocaddress_with_api ...
+#define GO(A) \
+static int my_getprocaddress_api_##A = 0; \
+static void* my_getprocaddress_with_api_##A(const char* name) \
+{ \
+ return my->gst_gl_context_default_get_proc_address(my_getprocaddress_api_##A, (void*)name); \
+}
+SUPER()
+#undef GO
+static glprocaddress_t findGetProcAddressAPIFct(int api)
+{
+ #define GO(A) if(my_getprocaddress_api_##A == api) return my_getprocaddress_with_api_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_getprocaddress_api_##A == 0) {my_getprocaddress_api_##A = api; return my_getprocaddress_with_api_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl gst_gl_context_default_get_proc_address callback\n");
+ return NULL;
+}
+// GDestroyFunc ...
+#define GO(A) \
+static uintptr_t my_destroyfunc_fct_##A = 0; \
+static int my_destroyfunc_##A(void* a, void* b) \
+{ \
+ return RunFunctionFmt(my_destroyfunc_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* findDestroyFct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_destroyfunc_fct_##A == (uintptr_t)fct) return my_destroyfunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_destroyfunc_fct_##A == 0) {my_destroyfunc_fct_##A = (uintptr_t)fct; return my_destroyfunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl GDestroyNotify callback\n");
+ return NULL;
+}
+//GstGLContextThreadFunc
+#define GO(A) \
+static uintptr_t my_GstGLContextThreadFunc_fct_##A = 0; \
+static void my_GstGLContextThreadFunc_##A(void* a, void* b) \
+{ \
+ RunFunctionFmt(my_GstGLContextThreadFunc_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* findGstGLContextThreadFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstGLContextThreadFunc_fct_##A == (uintptr_t)fct) return my_GstGLContextThreadFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstGLContextThreadFunc_fct_##A == 0) {my_GstGLContextThreadFunc_fct_##A = (uintptr_t)fct; return my_GstGLContextThreadFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl GstGLContextThreadFunc callback\n");
+ return NULL;
+}
+//GstGLFilterRenderFunc
+#define GO(A) \
+static uintptr_t my_GstGLFilterRenderFunc_fct_##A = 0; \
+static int my_GstGLFilterRenderFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstGLFilterRenderFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstGLFilterRenderFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstGLFilterRenderFunc_fct_##A == (uintptr_t)fct) return my_GstGLFilterRenderFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstGLFilterRenderFunc_fct_##A == 0) {my_GstGLFilterRenderFunc_fct_##A = (uintptr_t)fct; return my_GstGLFilterRenderFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl GstGLFilterRenderFunc callback\n");
+ return NULL;
+}
+//GstGLFramebufferFunc
+#define GO(A) \
+static uintptr_t my_GstGLFramebufferFunc_fct_##A = 0; \
+static int my_GstGLFramebufferFunc_##A(void* a) \
+{ \
+ return (int)RunFunctionFmt(my_GstGLFramebufferFunc_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGstGLFramebufferFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstGLFramebufferFunc_fct_##A == (uintptr_t)fct) return my_GstGLFramebufferFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstGLFramebufferFunc_fct_##A == 0) {my_GstGLFramebufferFunc_fct_##A = (uintptr_t)fct; return my_GstGLFramebufferFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl GstGLFramebufferFunc callback\n");
+ return NULL;
+}
+//GstGLWindowCB
+#define GO(A) \
+static uintptr_t my_GstGLWindowCB_fct_##A = 0; \
+static void my_GstGLWindowCB_##A(void* a) \
+{ \
+ RunFunctionFmt(my_GstGLWindowCB_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGstGLWindowCBFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstGLWindowCB_fct_##A == (uintptr_t)fct) return my_GstGLWindowCB_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstGLWindowCB_fct_##A == 0) {my_GstGLWindowCB_fct_##A = (uintptr_t)fct; return my_GstGLWindowCB_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstgl GstGLWindowCB callback\n");
+ return NULL;
+}
+#undef SUPER
+
+EXPORT void* my_gst_gl_context_get_proc_address_with_platform(x64emu_t* emu, int type, int gl_api, const char* name)
+{
+ return getGLProcAddress(emu, findGetProcAddressPlatformFct(type, gl_api), name);
+}
+
+EXPORT void* my_gst_gl_context_default_get_proc_address(x64emu_t* emu, int gl_api, const char* name)
+{
+ return getGLProcAddress(emu, findGetProcAddressAPIFct(gl_api), name);
+}
+
+EXPORT void my_gst_gl_context_thread_add(x64emu_t* emu, void* context, void* f, void* data)
+{
+ my->gst_gl_context_thread_add(context, findGstGLContextThreadFuncFct(f), data);
+}
+
+EXPORT int my_gst_gl_filter_render_to_target(x64emu_t* emu, void* filter, void* input, void* output, void* f, void* data)
+{
+ return my->gst_gl_filter_render_to_target(filter, input, output, findGstGLFilterRenderFuncFct(f), data);
+}
+
+EXPORT int my_gst_gl_framebuffer_draw_to_texture(x64emu_t* emu, void* fb, void* mem, void* f, void* data)
+{
+ return my->gst_gl_framebuffer_draw_to_texture(fb, mem, findGstGLFramebufferFuncFct(f), data);
+}
+
+EXPORT void my_gst_gl_insert_debug_marker(x64emu_t* emu, void* context, void* fmt, uintptr_t* b)
+{
+ #ifdef PREFER_CONVERT_VAARG
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 2);
+ #else
+ myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 2);
+ PREPARE_VALIST;
+ #endif
+ char* buff = NULL;
+ if(vasprintf(&buff, (const char*)fmt, VARARGS)<0)
+ return; // meh
+ my->gst_gl_insert_debug_marker(context, buff);
+ free(buff);
+}
+
+EXPORT void my_gst_gl_window_send_message(x64emu_t* emu, void* window, void* f, void* data)
+{
+ my->gst_gl_window_send_message(window, findGstGLWindowCBFct(f), data);
+}
+
+EXPORT void my_gst_gl_window_set_close_callback(x64emu_t* emu, void* window, void* f, void* data, void* d)
+{
+ my->gst_gl_window_set_close_callback(window, findGstGLWindowCBFct(f), data, findDestroyFct(d));
+}
+
+EXPORT void my_gst_gl_window_set_draw_callback(x64emu_t* emu, void* window, void* f, void* data, void* d)
+{
+ my->gst_gl_window_set_draw_callback(window, findGstGLWindowCBFct(f), data, findDestroyFct(d));
+}
+
+EXPORT void my_gst_gl_window_set_resize_callback(x64emu_t* emu, void* window, void* f, void* data, void* d)
+{
+ my->gst_gl_window_set_resize_callback(window, findGstGLWindowCBFct(f), data, findDestroyFct(d));
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
+#define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstGLBaseFilterID(my->gst_gl_base_filter_get_type()); \
+ SetGstGLFilterID(my->gst_gl_filter_get_type()); \
+ SetGstGLBaseSrcID(my->gst_gl_base_src_get_type()); \
+ setNeededLibs(lib, 2, "libGL.so.1", "libgstreamer-1.0.so.0");
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstgl_private.h b/src/wrapped/wrappedgstgl_private.h
index 6ca18cc..92e247c 100644
--- a/src/wrapped/wrappedgstgl_private.h
+++ b/src/wrapped/wrappedgstgl_private.h
@@ -2,29 +2,29 @@
#error meh!
#endif
-//GO(gst_buffer_add_gl_sync_meta,
+GO(gst_buffer_add_gl_sync_meta, pFpp)
//GO(gst_buffer_add_gl_sync_meta_full,
//GO(gst_buffer_pool_config_get_gl_allocation_params,
//GO(gst_buffer_pool_config_set_gl_allocation_params,
GO(gst_context_get_gl_display, iFpp)
GO(gst_context_set_gl_display, vFpp)
//GO(gst_egl_get_error_string,
-//GO(gst_egl_image_export_dmabuf,
+GO(gst_egl_image_export_dmabuf, iFpppp)
//GO(gst_egl_image_from_dmabuf,
//GO(gst_egl_image_from_dmabuf_direct,
//GO(gst_egl_image_from_dmabuf_direct_target,
-//GO(gst_egl_image_from_texture,
+GO(gst_egl_image_from_texture, pFppp)
//GO(gst_egl_image_get_image,
-//GO(gst_egl_image_get_type,
+GO(gst_egl_image_get_type, LFv)
//GO(gst_egl_image_new_wrapped,
//GO(gst_gl_allocation_params_copy,
//GO(gst_gl_allocation_params_copy_data,
-//GO(gst_gl_allocation_params_free,
+GO(gst_gl_allocation_params_free, vFp)
//GO(gst_gl_allocation_params_free_data,
-//GO(gst_gl_allocation_params_get_type,
+GO(gst_gl_allocation_params_get_type, LFv)
//GO(gst_gl_allocation_params_init,
GO(gst_gl_api_from_string, uFp)
-//GO(gst_gl_api_get_type,
+GO(gst_gl_api_get_type, LFv)
GO(gst_gl_api_to_string, pFu)
//GO(gst_gl_async_debug_free,
//GO(gst_gl_async_debug_freeze,
@@ -35,36 +35,36 @@ GO(gst_gl_api_to_string, pFu)
//GO(gst_gl_async_debug_store_log_msg_valist,
//GO(gst_gl_async_debug_thaw,
//GO(gst_gl_async_debug_unset,
-//GO(gst_gl_base_filter_find_gl_context,
-//GO(gst_gl_base_filter_get_gl_context,
-//GO(gst_gl_base_filter_get_type,
-//GO(gst_gl_base_memory_alloc,
-//GO(gst_gl_base_memory_allocator_get_type,
+GO(gst_gl_base_filter_find_gl_context, iFp)
+GO(gst_gl_base_filter_get_gl_context, pFp)
+GO(gst_gl_base_filter_get_type, LFv)
+GO(gst_gl_base_memory_alloc, pFpp)
+GO(gst_gl_base_memory_allocator_get_type, LFv)
//GO(gst_gl_base_memory_alloc_data,
-//GO(gst_gl_base_memory_error_get_type,
+GO(gst_gl_base_memory_error_get_type, LFv)
GO(gst_gl_base_memory_error_quark, uFv)
-//GO(gst_gl_base_memory_get_type,
+GO(gst_gl_base_memory_get_type, LFv)
//GO(gst_gl_base_memory_init,
//GO(gst_gl_base_memory_init_once,
//GO(gst_gl_base_memory_memcpy,
-//GO(gst_gl_base_memory_transfer_get_type,
-//GO(gst_gl_base_src_get_type,
-//GO(gst_gl_buffer_allocation_params_get_type,
+GO(gst_gl_base_memory_transfer_get_type, LFv)
+GO(gst_gl_base_src_get_type, LFv)
+GO(gst_gl_buffer_allocation_params_get_type, LFv)
//GO(gst_gl_buffer_allocation_params_new,
-//GO(gst_gl_buffer_allocator_get_type,
-//GO(gst_gl_buffer_get_type,
+GO(gst_gl_buffer_allocator_get_type, LFv)
+GO(gst_gl_buffer_get_type, LFv)
//GO(gst_gl_buffer_init_once,
//GO(gst_gl_buffer_pool_get_gl_allocation_params,
-//GO(gst_gl_buffer_pool_get_type,
-//GO(gst_gl_buffer_pool_new,
+GO(gst_gl_buffer_pool_get_type, LFv)
+GO(gst_gl_buffer_pool_new, pFp)
GO(gst_gl_check_extension, iFpp)
-//GO(gst_gl_color_convert_decide_allocation,
-//GO(gst_gl_color_convert_fixate_caps,
-//GO(gst_gl_color_convert_get_type,
-//GO(gst_gl_color_convert_new,
-//GO(gst_gl_color_convert_perform,
-//GO(gst_gl_color_convert_set_caps,
-//GO(gst_gl_color_convert_transform_caps,
+GO(gst_gl_color_convert_decide_allocation, iFpp)
+GO(gst_gl_color_convert_fixate_caps, pFpipp)
+GO(gst_gl_color_convert_get_type, LFv)
+GO(gst_gl_color_convert_new, pFp)
+GO(gst_gl_color_convert_perform, pFpp)
+GO(gst_gl_color_convert_set_caps, iFppp)
+GO(gst_gl_color_convert_transform_caps, pFpipp)
//DATA(GST_GL_CONFIG_ATTRIB_ALPHA_SIZE_NAME,
//DATA(GST_GL_CONFIG_ATTRIB_BLUE_SIZE_NAME,
//DATA(GST_GL_CONFIG_ATTRIB_CAVEAT_NAME,
@@ -88,38 +88,38 @@ GO(gst_gl_check_extension, iFpp)
//DATA(GST_GL_CONFIG_ATTRIB_SAMPLES_NAME,
//DATA(GST_GL_CONFIG_ATTRIB_STENCIL_SIZE_NAME,
//DATA(GST_GL_CONFIG_ATTRIB_SURFACE_TYPE_NAME,
-//GO(gst_gl_config_caveat_get_type,
+GO(gst_gl_config_caveat_get_type, LFv)
GO(gst_gl_config_caveat_to_string, pFu)
-//GO(gst_gl_config_surface_type_get_type,
+GO(gst_gl_config_surface_type_get_type, LFv)
GO(gst_gl_config_surface_type_to_string, pFu)
//GO(gst_gl_context_activate,
//GO(gst_gl_context_can_share,
//GO(gst_gl_context_check_feature,
//GO(gst_gl_context_check_framebuffer_status,
-//GO(gst_gl_context_check_gl_version,
+GO(gst_gl_context_check_gl_version, iFpiii)
//GO(gst_gl_context_clear_framebuffer,
-//GO(gst_gl_context_clear_shader,
+GO(gst_gl_context_clear_shader, vFp)
//GO(gst_gl_context_create,
-GO(gst_gl_context_default_get_proc_address, pFup)
+GOM(gst_gl_context_default_get_proc_address, pFEup)
//GO(gst_gl_context_destroy,
-//GO(gst_gl_context_error_get_type,
+GO(gst_gl_context_error_get_type, LFv)
//GO(gst_gl_context_error_quark,
//GO(gst_gl_context_fill_info,
//GO(gst_gl_context_get_config,
-//GO(gst_gl_context_get_current,
+GO(gst_gl_context_get_current, pFv)
GO(gst_gl_context_get_current_gl_api, uFupp)
GO(gst_gl_context_get_current_gl_context, LFu)
//GO(gst_gl_context_get_display,
-//GO(gst_gl_context_get_gl_api,
+GO(gst_gl_context_get_gl_api, iFp)
//GO(gst_gl_context_get_gl_context,
-//GO(gst_gl_context_get_gl_platform,
+GO(gst_gl_context_get_gl_platform, iFp)
//GO(gst_gl_context_get_gl_platform_version,
//GO(gst_gl_context_get_gl_version,
//GO(gst_gl_context_get_proc_address,
-GO(gst_gl_context_get_proc_address_with_platform, pFuup)
+GOM(gst_gl_context_get_proc_address_with_platform, pFEuup)
//GO(gst_gl_context_get_thread,
-//GO(gst_gl_context_get_type,
-//GO(gst_gl_context_get_window,
+GO(gst_gl_context_get_type, LFv)
+GO(gst_gl_context_get_window, pFp)
//GO(gst_gl_context_is_shared,
//GO(gst_gl_context_new,
//GO(gst_gl_context_new_wrapped,
@@ -130,100 +130,100 @@ GO(gst_gl_context_get_proc_address_with_platform, pFuup)
//GO(gst_gl_context_supports_precision,
//GO(gst_gl_context_supports_precision_highp,
//GO(gst_gl_context_swap_buffers,
-//GO(gst_gl_context_thread_add,
+GOM(gst_gl_context_thread_add, vFEppp)
GO(gst_gl_display_add_context, iFpp)
GO(gst_gl_display_create_context, iFpppp)
//GO(gst_gl_display_create_window,
-//GO(gst_gl_display_egl_device_get_type,
+GO(gst_gl_display_egl_device_get_type, LFv)
//GO(gst_gl_display_egl_device_new,
//GO(gst_gl_display_egl_device_new_with_egl_device,
//GO(gst_gl_display_egl_from_gl_display,
//GO(gst_gl_display_egl_get_from_native,
-//GO(gst_gl_display_egl_get_type,
+GO(gst_gl_display_egl_get_type, LFv)
//GO(gst_gl_display_egl_new,
//GO(gst_gl_display_egl_new_with_egl_display,
-//GO(gst_gl_display_filter_gl_api,
+GO(gst_gl_display_filter_gl_api, vFpi)
//GO(gst_gl_display_find_window,
//GO(gst_gl_display_get_gl_api,
//GO(gst_gl_display_get_gl_api_unlocked,
-//GO(gst_gl_display_get_gl_context_for_thread,
+GO(gst_gl_display_get_gl_context_for_thread, pFpp)
//GO(gst_gl_display_get_handle,
//GO(gst_gl_display_get_handle_type,
-//GO(gst_gl_display_get_type,
+GO(gst_gl_display_get_type, LFv)
GO(gst_gl_display_new, pFv)
GO(gst_gl_display_new_with_type, pFi)
//GO(gst_gl_display_remove_context,
//GO(gst_gl_display_remove_window,
//GO(gst_gl_display_retrieve_window,
-//GO(gst_gl_display_type_get_type,
-//GO(gst_gl_display_wayland_get_type,
+GO(gst_gl_display_type_get_type, LFv)
+GO(gst_gl_display_wayland_get_type, LFv)
//GO(gst_gl_display_wayland_new,
//GO(gst_gl_display_wayland_new_with_display,
-//GO(gst_gl_display_x11_get_type,
+GO(gst_gl_display_x11_get_type, LFv)
//GO(gst_gl_display_x11_new,
//GO(gst_gl_display_x11_new_with_display,
//GO(gst_gl_element_propagate_display_context,
GO(gst_gl_ensure_element_data, iFppp)
-//GO(gst_gl_filter_add_rgba_pad_templates,
-//GO(gst_gl_filter_draw_fullscreen_quad,
-//GO(gst_gl_filter_filter_texture,
-//GO(gst_gl_filter_get_type,
-//GO(gst_gl_filter_render_to_target,
-//GO(gst_gl_filter_render_to_target_with_shader,
+GO(gst_gl_filter_add_rgba_pad_templates, vFp)
+GO(gst_gl_filter_draw_fullscreen_quad, vFp)
+GO(gst_gl_filter_filter_texture, iFppp)
+GO(gst_gl_filter_get_type, LFv)
+GOM(gst_gl_filter_render_to_target, iFEppppp)
+GO(gst_gl_filter_render_to_target_with_shader, vFpppp)
//GO(gst_gl_format_from_video_info,
-//GO(gst_gl_format_get_type,
+GO(gst_gl_format_get_type, LFv)
//GO(gst_gl_format_is_supported,
GO(gst_gl_format_type_from_sized_gl_format, vFupp)
GO(gst_gl_format_type_n_bytes, uFuu)
//GO(gst_gl_framebuffer_attach,
//GO(gst_gl_framebuffer_bind,
-//GO(gst_gl_framebuffer_draw_to_texture,
+GOM(gst_gl_framebuffer_draw_to_texture, iFEpppp)
GO(gst_gl_framebuffer_get_effective_dimensions, vFppp)
GO(gst_gl_framebuffer_get_id, uFp)
-//GO(gst_gl_framebuffer_get_type,
+GO(gst_gl_framebuffer_get_type, LFv)
//GO(gst_gl_framebuffer_new,
-//GO(gst_gl_framebuffer_new_with_default_depth,
-//GO(gst_gl_get_affine_transformation_meta_as_ndc,
+GO(gst_gl_framebuffer_new_with_default_depth, pFpuu)
+GO(gst_gl_get_affine_transformation_meta_as_ndc, vFpp)
//GO(gst_gl_get_plane_data_size,
//GO(gst_gl_get_plane_start,
-//GO(gst_gl_handle_context_query,
+GO(gst_gl_handle_context_query, iFppppp)
GO(gst_gl_handle_set_context, iFpppp)
-//GO(gst_gl_insert_debug_marker,
+GOM(gst_gl_insert_debug_marker, vFppV)
//GO(gst_gl_memory_allocator_get_default,
-//GO(gst_gl_memory_allocator_get_type,
+GO(gst_gl_memory_allocator_get_type, LFv)
//GO(gst_gl_memory_copy_into,
//GO(gst_gl_memory_copy_teximage,
-//GO(gst_gl_memory_egl_allocator_get_type,
+GO(gst_gl_memory_egl_allocator_get_type, LFv)
//GO(gst_gl_memory_egl_get_display,
//GO(gst_gl_memory_egl_get_image,
-//GO(gst_gl_memory_egl_get_type,
+GO(gst_gl_memory_egl_get_type, LFv)
//GO(gst_gl_memory_egl_init_once,
//GO(gst_gl_memory_get_texture_format,
-//GO(gst_gl_memory_get_texture_height,
-//GO(gst_gl_memory_get_texture_id,
-//GO(gst_gl_memory_get_texture_target,
-//GO(gst_gl_memory_get_texture_width,
-//GO(gst_gl_memory_get_type,
+GO(gst_gl_memory_get_texture_height, iFp)
+GO(gst_gl_memory_get_texture_id, uFp)
+GO(gst_gl_memory_get_texture_target, iFp)
+GO(gst_gl_memory_get_texture_width, iFp)
+GO(gst_gl_memory_get_type, LFv)
//GO(gst_gl_memory_init,
//GO(gst_gl_memory_init_once,
-//GO(gst_gl_memory_pbo_allocator_get_type,
+GO(gst_gl_memory_pbo_allocator_get_type, LFv)
//GO(gst_gl_memory_pbo_copy_into_texture,
-//GO(gst_gl_memory_pbo_download_transfer,
-//GO(gst_gl_memory_pbo_get_type,
+GO(gst_gl_memory_pbo_download_transfer, vFp)
+GO(gst_gl_memory_pbo_get_type, LFv)
//GO(gst_gl_memory_pbo_init_once,
//GO(gst_gl_memory_pbo_upload_transfer,
//GO(gst_gl_memory_read_pixels,
//GO(gst_gl_memory_setup_buffer,
//GO(gst_gl_memory_texsubimage,
GO(gst_gl_multiply_matrix4, vFppp)
-//GO(gst_gl_overlay_compositor_add_caps,
-//GO(gst_gl_overlay_compositor_draw_overlays,
-//GO(gst_gl_overlay_compositor_free_overlays,
+GO(gst_gl_overlay_compositor_add_caps, pFp)
+GO(gst_gl_overlay_compositor_draw_overlays, vFp)
+GO(gst_gl_overlay_compositor_free_overlays, vFp)
GO(gst_gl_overlay_compositor_get_type, LFv)
-//GO(gst_gl_overlay_compositor_new,
-//GO(gst_gl_overlay_compositor_upload_overlays,
+GO(gst_gl_overlay_compositor_new, pFp)
+GO(gst_gl_overlay_compositor_upload_overlays, vFpp)
GO(gst_gl_platform_from_string, uFp)
-//GO(gst_gl_platform_get_type,
+GO(gst_gl_platform_get_type, LFv)
GO(gst_gl_platform_to_string, pFu)
//GO(gst_gl_query_counter,
//GO(gst_gl_query_end,
@@ -233,39 +233,39 @@ GO(gst_gl_query_local_gl_context, iFpup)
//GO(gst_gl_query_new,
//GO(gst_gl_query_result,
//GO(gst_gl_query_start,
-//GO(gst_gl_query_type_get_type,
+GO(gst_gl_query_type_get_type, LFv)
//GO(gst_gl_query_unset,
-//GO(gst_gl_renderbuffer_allocation_params_get_type,
+GO(gst_gl_renderbuffer_allocation_params_get_type, LFv)
//GO(gst_gl_renderbuffer_allocation_params_new,
//GO(gst_gl_renderbuffer_allocation_params_new_wrapped,
-//GO(gst_gl_renderbuffer_allocator_get_type,
+GO(gst_gl_renderbuffer_allocator_get_type, LFv)
//GO(gst_gl_renderbuffer_get_format,
//GO(gst_gl_renderbuffer_get_height,
//GO(gst_gl_renderbuffer_get_id,
-//GO(gst_gl_renderbuffer_get_type,
+GO(gst_gl_renderbuffer_get_type, LFv)
//GO(gst_gl_renderbuffer_get_width,
GO(gst_gl_renderbuffer_init_once, vFv)
-//GO(gst_gl_set_affine_transformation_meta_from_ndc,
-//GO(gst_gl_shader_attach,
-//GO(gst_gl_shader_attach_unlocked,
-//GO(gst_gl_shader_bind_attribute_location,
+GO(gst_gl_set_affine_transformation_meta_from_ndc, vFpp)
+GO(gst_gl_shader_attach, iFpp)
+GO(gst_gl_shader_attach_unlocked, iFpp)
+GO(gst_gl_shader_bind_attribute_location, vFpup)
GO(gst_gl_shader_bind_frag_data_location, vFpup)
-//GO(gst_gl_shader_compile_attach_stage,
-//GO(gst_gl_shader_detach,
-//GO(gst_gl_shader_detach_unlocked,
+GO(gst_gl_shader_compile_attach_stage, iFppp)
+GO(gst_gl_shader_detach, vFpp)
+GO(gst_gl_shader_detach_unlocked, vFpp)
GO(gst_gl_shader_get_attribute_location, iFpp)
GO(gst_gl_shader_get_program_handle, iFp)
-//GO(gst_gl_shader_get_type,
+GO(gst_gl_shader_get_type, LFv)
GO(gst_gl_shader_is_linked, iFp)
GO(gst_gl_shader_link, iFpp)
-//GO(gst_gl_shader_new,
-//GO(gst_gl_shader_new_default,
-//GO(gst_gl_shader_new_link_with_stages,
-//GO(gst_gl_shader_new_with_stages,
+GO(gst_gl_shader_new, pFp)
+GO(gst_gl_shader_new_default, pFpp)
+GO(gst_gl_shader_new_link_with_stages, pFpppppppppppp) //vaargs
+GO(gst_gl_shader_new_with_stages, pFpppppppppppp) //vaarg
//GO(gst_gl_shader_release,
//GO(gst_gl_shader_release_unlocked,
GO(gst_gl_shader_set_uniform_1f, vFppf)
-//GO(gst_gl_shader_set_uniform_1fv,
+GO(gst_gl_shader_set_uniform_1fv, vFppup)
GO(gst_gl_shader_set_uniform_1i, vFppi)
//GO(gst_gl_shader_set_uniform_1iv,
GO(gst_gl_shader_set_uniform_2f, vFppff)
@@ -286,121 +286,121 @@ GO(gst_gl_shader_set_uniform_4iv, vFppup)
//GO(gst_gl_shader_set_uniform_matrix_3fv,
//GO(gst_gl_shader_set_uniform_matrix_3x2fv,
//GO(gst_gl_shader_set_uniform_matrix_3x4fv,
-//GO(gst_gl_shader_set_uniform_matrix_4fv,
+GO(gst_gl_shader_set_uniform_matrix_4fv, vFppiip)
//GO(gst_gl_shader_set_uniform_matrix_4x2fv,
GO(gst_gl_shader_set_uniform_matrix_4x3fv, vFppiip)
//DATA(gst_gl_shader_string_fragment_default,
//DATA(gst_gl_shader_string_fragment_external_oes_default,
-//GO(gst_gl_shader_string_fragment_external_oes_get_default,
-//GO(gst_gl_shader_string_fragment_get_default,
-//DATA(gst_gl_shader_string_fragment_highp_precision,
-//DATA(gst_gl_shader_string_fragment_mediump_precision,
-//GO(gst_gl_shader_string_get_highest_precision,
-//DATA(gst_gl_shader_string_vertex_default,
-//DATA(gst_gl_shader_string_vertex_mat4_texture_transform,
-//DATA(gst_gl_shader_string_vertex_mat4_vertex_transform,
+GO(gst_gl_shader_string_fragment_external_oes_get_default, pFpii)
+GO(gst_gl_shader_string_fragment_get_default, pFpii)
+DATA(gst_gl_shader_string_fragment_highp_precision, sizeof(void*))
+DATA(gst_gl_shader_string_fragment_mediump_precision, sizeof(void*))
+GO(gst_gl_shader_string_get_highest_precision, pFpii)
+DATA(gst_gl_shader_string_vertex_default, sizeof(void*))
+DATA(gst_gl_shader_string_vertex_mat4_texture_transform, sizeof(void*))
+DATA(gst_gl_shader_string_vertex_mat4_vertex_transform, sizeof(void*))
GO(gst_gl_shader_use, vFp)
//GO(gst_gl_sized_gl_format_from_gl_format_type,
-//GO(gst_glsl_error_get_type,
-//GO(gst_glsl_error_quark,
+GO(gst_glsl_error_get_type, LFv)
+GO(gst_glsl_error_quark, pFv)
GO(gst_glsl_profile_from_string, iFp)
-//GO(gst_glsl_profile_get_type,
+GO(gst_glsl_profile_get_type, LFv)
GO(gst_glsl_profile_to_string, pFi)
-//GO(gst_glsl_stage_compile,
+GO(gst_glsl_stage_compile, iFpp)
//GO(gst_glsl_stage_get_handle,
//GO(gst_glsl_stage_get_profile,
//GO(gst_glsl_stage_get_shader_type,
-//GO(gst_glsl_stage_get_type,
+GO(gst_glsl_stage_get_type, LFv)
//GO(gst_glsl_stage_get_version,
//GO(gst_glsl_stage_new,
-//GO(gst_glsl_stage_new_default_fragment,
-//GO(gst_glsl_stage_new_default_vertex,
-//GO(gst_glsl_stage_new_with_string,
-//GO(gst_glsl_stage_new_with_strings,
+GO(gst_glsl_stage_new_default_fragment, pFp)
+GO(gst_glsl_stage_new_default_vertex, pFp)
+GO(gst_glsl_stage_new_with_string, pFpuiip)
+GO(gst_glsl_stage_new_with_strings, pFpuiiip)
//GO(gst_glsl_stage_set_strings,
GO(gst_glsl_string_get_version_profile, iFppp)
GO(gst_glsl_version_from_string, uFp)
-//GO(gst_glsl_version_get_type,
+GO(gst_glsl_version_get_type, LFv)
//GO(gst_glsl_version_profile_from_string,
GO(gst_glsl_version_profile_to_string, pFui)
GO(gst_glsl_version_to_string, pFu)
-//GO(gst_gl_stereo_downmix_get_type,
-//GO(gst_gl_stereo_downmix_mode_get_type,
-//GO(gst_gl_sync_meta_api_get_type,
+GO(gst_gl_stereo_downmix_get_type, LFv)
+GO(gst_gl_stereo_downmix_mode_get_type, LFv)
+GO(gst_gl_sync_meta_api_get_type, LFv)
//GO(gst_gl_sync_meta_get_info,
-//GO(gst_gl_sync_meta_set_sync_point,
-//GO(gst_gl_sync_meta_wait,
-//GO(gst_gl_sync_meta_wait_cpu,
+GO(gst_gl_sync_meta_set_sync_point, vFpp)
+GO(gst_gl_sync_meta_wait, vFpp)
+GO(gst_gl_sync_meta_wait_cpu, vFpp)
GO(gst_gl_texture_target_from_gl, uFu)
GO(gst_gl_texture_target_from_string, uFp)
-//GO(gst_gl_texture_target_get_type,
+GO(gst_gl_texture_target_get_type, LFv)
GO(gst_gl_texture_target_to_buffer_pool_option, pFu)
GO(gst_gl_texture_target_to_gl, uFu)
-//GO(gst_gl_texture_target_to_string,
-//GO(gst_gl_upload_get_caps,
-//GO(gst_gl_upload_get_input_template_caps,
-//GO(gst_gl_upload_get_type,
-//GO(gst_gl_upload_new,
-//GO(gst_gl_upload_perform_with_buffer,
-//GO(gst_gl_upload_propose_allocation,
-//GO(gst_gl_upload_return_get_type,
-//GO(gst_gl_upload_set_caps,
-//GO(gst_gl_upload_set_context,
-//GO(gst_gl_upload_transform_caps,
+GO(gst_gl_texture_target_to_string, pFi)
+GO(gst_gl_upload_get_caps, vFppp)
+GO(gst_gl_upload_get_input_template_caps, pFv)
+GO(gst_gl_upload_get_type, LFv)
+GO(gst_gl_upload_new, pFp)
+GO(gst_gl_upload_perform_with_buffer, iFppp)
+GO(gst_gl_upload_propose_allocation, vFppp)
+GO(gst_gl_upload_return_get_type, LFv)
+GO(gst_gl_upload_set_caps, iFppp)
+GO(gst_gl_upload_set_context, vFpp)
+GO(gst_gl_upload_transform_caps, pFppipp)
GO(gst_gl_value_get_texture_target_mask, uFp)
GO(gst_gl_value_set_texture_target, iFpu)
//GO(gst_gl_value_set_texture_target_from_mask,
GO(gst_gl_version_to_glsl_version, uFuii)
//GO(gst_gl_video_allocation_params_copy_data,
//GO(gst_gl_video_allocation_params_free_data,
-//GO(gst_gl_video_allocation_params_get_type,
+GO(gst_gl_video_allocation_params_get_type, LFv)
//GO(gst_gl_video_allocation_params_init_full,
-//GO(gst_gl_video_allocation_params_new,
+GO(gst_gl_video_allocation_params_new, pFpppupii)
//GO(gst_gl_video_allocation_params_new_wrapped_data,
//GO(gst_gl_video_allocation_params_new_wrapped_gl_handle,
//GO(gst_gl_video_allocation_params_new_wrapped_texture,
-//GO(gst_gl_view_convert_fixate_caps,
-//GO(gst_gl_view_convert_get_output,
-//GO(gst_gl_view_convert_get_type,
-//GO(gst_gl_view_convert_new,
-//GO(gst_gl_view_convert_perform,
-//GO(gst_gl_view_convert_reset,
-//GO(gst_gl_view_convert_set_caps,
-//GO(gst_gl_view_convert_set_context,
-//GO(gst_gl_view_convert_submit_input_buffer,
-//GO(gst_gl_view_convert_transform_caps,
-//GO(gst_gl_window_controls_viewport,
-//GO(gst_gl_window_draw,
-//GO(gst_gl_window_error_get_type,
-//GO(gst_gl_window_error_quark,
+GO(gst_gl_view_convert_fixate_caps, pFpipp)
+GO(gst_gl_view_convert_get_output, iFpp)
+GO(gst_gl_view_convert_get_type, LFv)
+GO(gst_gl_view_convert_new, pFv)
+GO(gst_gl_view_convert_perform, pFpp)
+GO(gst_gl_view_convert_reset, vFp)
+GO(gst_gl_view_convert_set_caps, iFppp)
+GO(gst_gl_view_convert_set_context, vFpp)
+GO(gst_gl_view_convert_submit_input_buffer, iFpip)
+GO(gst_gl_view_convert_transform_caps, pFpipp)
+GO(gst_gl_window_controls_viewport, iFp)
+GO(gst_gl_window_draw, iFp)
+GO(gst_gl_window_error_get_type, LFv)
+GO(gst_gl_window_error_quark, pFv)
//GO(gst_gl_window_get_context,
//GO(gst_gl_window_get_display,
-//GO(gst_gl_window_get_surface_dimensions,
-//GO(gst_gl_window_get_type,
+GO(gst_gl_window_get_surface_dimensions, vFppp)
+GO(gst_gl_window_get_type, LFv)
//GO(gst_gl_window_get_window_handle,
-//GO(gst_gl_window_handle_events,
+GO(gst_gl_window_handle_events, vFpi)
//GO(gst_gl_window_has_output_surface,
//GO(gst_gl_window_new,
-//GO(gst_gl_window_queue_resize,
+GO(gst_gl_window_queue_resize, vFp)
//GO(gst_gl_window_quit,
//GO(gst_gl_window_resize,
//GO(gst_gl_window_run,
//GO(gst_gl_window_send_key_event,
-//GO(gst_gl_window_send_message,
+GOM(gst_gl_window_send_message, vFEppp)
//GO(gst_gl_window_send_message_async,
//GO(gst_gl_window_send_mouse_event,
//GO(gst_gl_window_send_scroll_event,
-//GO(gst_gl_window_set_close_callback,
-//GO(gst_gl_window_set_draw_callback,
-//GO(gst_gl_window_set_preferred_size,
-//GO(gst_gl_window_set_render_rectangle,
-//GO(gst_gl_window_set_resize_callback,
-//GO(gst_gl_window_set_window_handle,
-//GO(gst_gl_window_show,
+GOM(gst_gl_window_set_close_callback, vFEpppp)
+GOM(gst_gl_window_set_draw_callback, vFEpppp)
+GO(gst_gl_window_set_preferred_size, vFpii)
+GO(gst_gl_window_set_render_rectangle, iFpiiii)
+GOM(gst_gl_window_set_resize_callback, vFEpppp)
+GO(gst_gl_window_set_window_handle, vFpL)
+GO(gst_gl_window_show, vFp)
//GO(gst_is_gl_base_memory,
//GO(gst_is_gl_buffer,
//GO(gst_is_gl_memory,
//GO(gst_is_gl_memory_egl,
-//GO(gst_is_gl_memory_pbo,
+GO(gst_is_gl_memory_pbo, iFp)
//GO(gst_is_gl_renderbuffer,
diff --git a/src/wrapped/wrappedgstnet.c b/src/wrapped/wrappedgstnet.c
new file mode 100644
index 0000000..53c09dc
--- /dev/null
+++ b/src/wrapped/wrappedgstnet.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstnetName = "libgstnet-1.0.so";
+#else
+ const char* gstnetName = "libgstnet-1.0.so.0";
+#endif
+
+#define LIBNAME gstnet
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstnet_private.h b/src/wrapped/wrappedgstnet_private.h
new file mode 100644
index 0000000..03a500c
--- /dev/null
+++ b/src/wrapped/wrappedgstnet_private.h
@@ -0,0 +1,33 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+//GO(gst_buffer_add_net_address_meta,
+//GO(gst_buffer_add_net_control_message_meta,
+//GO(gst_buffer_get_net_address_meta,
+GO(gst_net_address_meta_api_get_type, LFv)
+//GO(gst_net_address_meta_get_info,
+GO(gst_net_client_clock_get_type, LFv)
+//GO(gst_net_client_clock_new,
+GO(gst_net_control_message_meta_api_get_type, LFv)
+//GO(gst_net_control_message_meta_get_info,
+//GO(gst_net_time_packet_copy,
+//GO(gst_net_time_packet_free,
+GO(gst_net_time_packet_get_type, LFv)
+//GO(gst_net_time_packet_new,
+//GO(gst_net_time_packet_receive,
+//GO(gst_net_time_packet_send,
+//GO(gst_net_time_packet_serialize,
+GO(gst_net_time_provider_get_type, LFv)
+//GO(gst_net_time_provider_new,
+//GO(gst_net_utils_set_socket_tos,
+GO(gst_ntp_clock_get_type, LFv)
+//GO(gst_ntp_clock_new,
+GO(gst_ptp_clock_get_type, LFv)
+//GO(gst_ptp_clock_new,
+//GO(gst_ptp_deinit,
+//GO(gst_ptp_init,
+//GO(gst_ptp_is_initialized,
+//GO(gst_ptp_is_supported,
+//GO(gst_ptp_statistics_callback_add,
+//GO(gst_ptp_statistics_callback_remove,
diff --git a/src/wrapped/wrappedgstpbutils.c b/src/wrapped/wrappedgstpbutils.c
new file mode 100644
index 0000000..eaa2ee3
--- /dev/null
+++ b/src/wrapped/wrappedgstpbutils.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstpbutilsName = "libgstpbutils-1.0.so";
+#else
+ const char* gstpbutilsName = "libgstpbutils-1.0.so.0";
+#endif
+
+#define LIBNAME gstpbutils
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstpbutils_private.h b/src/wrapped/wrappedgstpbutils_private.h
new file mode 100644
index 0000000..3957627
--- /dev/null
+++ b/src/wrapped/wrappedgstpbutils_private.h
@@ -0,0 +1,195 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(gst_audio_visualizer_get_type, LFv)
+GO(gst_audio_visualizer_shader_get_type, LFv)
+GO(gst_codec_utils_aac_caps_set_level_and_profile, iFppu)
+//GO(gst_codec_utils_aac_get_channels,
+//GO(gst_codec_utils_aac_get_index_from_sample_rate,
+//GO(gst_codec_utils_aac_get_level,
+//GO(gst_codec_utils_aac_get_profile,
+//GO(gst_codec_utils_aac_get_sample_rate,
+//GO(gst_codec_utils_aac_get_sample_rate_from_index,
+//GO(gst_codec_utils_caps_from_mime_codec,
+//GO(gst_codec_utils_caps_get_mime_codec,
+GO(gst_codec_utils_h264_caps_set_level_and_profile, iFppu)
+//GO(gst_codec_utils_h264_get_level,
+//GO(gst_codec_utils_h264_get_level_idc,
+//GO(gst_codec_utils_h264_get_profile,
+//GO(gst_codec_utils_h264_get_profile_flags_level,
+GO(gst_codec_utils_h265_caps_set_level_tier_and_profile, iFppu)
+//GO(gst_codec_utils_h265_get_level,
+//GO(gst_codec_utils_h265_get_level_idc,
+//GO(gst_codec_utils_h265_get_profile,
+//GO(gst_codec_utils_h265_get_tier,
+GO(gst_codec_utils_mpeg4video_caps_set_level_and_profile, iFppu)
+//GO(gst_codec_utils_mpeg4video_get_level,
+//GO(gst_codec_utils_mpeg4video_get_profile,
+GO(gst_codec_utils_opus_create_caps, pFuCCCCp)
+GO(gst_codec_utils_opus_create_caps_from_header, pFpp)
+GO(gst_codec_utils_opus_create_header, pFuCCCCpWw)
+GO(gst_codec_utils_opus_parse_caps, iFppppppp)
+//GO(gst_codec_utils_opus_parse_header,
+//GO(gst_discoverer_audio_info_get_bitrate,
+//GO(gst_discoverer_audio_info_get_channel_mask,
+//GO(gst_discoverer_audio_info_get_channels,
+//GO(gst_discoverer_audio_info_get_depth,
+//GO(gst_discoverer_audio_info_get_language,
+//GO(gst_discoverer_audio_info_get_max_bitrate,
+//GO(gst_discoverer_audio_info_get_sample_rate,
+GO(gst_discoverer_audio_info_get_type, LFv)
+//GO(gst_discoverer_container_info_get_streams,
+//GO(gst_discoverer_container_info_get_tags,
+GO(gst_discoverer_container_info_get_type, LFv)
+//GO(gst_discoverer_discover_uri,
+//GO(gst_discoverer_discover_uri_async,
+GO(gst_discoverer_get_type, LFv)
+//GO(gst_discoverer_info_copy,
+//GO(gst_discoverer_info_from_variant,
+//GO(gst_discoverer_info_get_audio_streams,
+//GO(gst_discoverer_info_get_container_streams,
+//GO(gst_discoverer_info_get_duration,
+//GO(gst_discoverer_info_get_live,
+//GO(gst_discoverer_info_get_misc,
+//GO(gst_discoverer_info_get_missing_elements_installer_details,
+//GO(gst_discoverer_info_get_result,
+//GO(gst_discoverer_info_get_seekable,
+//GO(gst_discoverer_info_get_stream_info,
+//GO(gst_discoverer_info_get_stream_list,
+//GO(gst_discoverer_info_get_streams,
+//GO(gst_discoverer_info_get_subtitle_streams,
+//GO(gst_discoverer_info_get_tags,
+//GO(gst_discoverer_info_get_toc,
+GO(gst_discoverer_info_get_type, LFv)
+//GO(gst_discoverer_info_get_uri,
+//GO(gst_discoverer_info_get_video_streams,
+//GO(gst_discoverer_info_to_variant,
+//GO(gst_discoverer_new,
+GO(gst_discoverer_result_get_type, LFv)
+GO(gst_discoverer_serialize_flags_get_type, LFv)
+//GO(gst_discoverer_start,
+//GO(gst_discoverer_stop,
+//GO(gst_discoverer_stream_info_get_caps,
+//GO(gst_discoverer_stream_info_get_misc,
+//GO(gst_discoverer_stream_info_get_next,
+//GO(gst_discoverer_stream_info_get_previous,
+//GO(gst_discoverer_stream_info_get_stream_id,
+//GO(gst_discoverer_stream_info_get_stream_number,
+//GO(gst_discoverer_stream_info_get_stream_type_nick,
+//GO(gst_discoverer_stream_info_get_tags,
+//GO(gst_discoverer_stream_info_get_toc,
+GO(gst_discoverer_stream_info_get_type, LFv)
+//GO(gst_discoverer_stream_info_list_free,
+//GO(gst_discoverer_subtitle_info_get_language,
+GO(gst_discoverer_subtitle_info_get_type, LFv)
+//GO(gst_discoverer_video_info_get_bitrate,
+//GO(gst_discoverer_video_info_get_depth,
+//GO(gst_discoverer_video_info_get_framerate_denom,
+//GO(gst_discoverer_video_info_get_framerate_num,
+//GO(gst_discoverer_video_info_get_height,
+//GO(gst_discoverer_video_info_get_max_bitrate,
+//GO(gst_discoverer_video_info_get_par_denom,
+//GO(gst_discoverer_video_info_get_par_num,
+GO(gst_discoverer_video_info_get_type, LFv)
+//GO(gst_discoverer_video_info_get_width,
+//GO(gst_discoverer_video_info_is_image,
+//GO(gst_discoverer_video_info_is_interlaced,
+GO(gst_encoding_audio_profile_get_type, LFv)
+//GO(gst_encoding_audio_profile_new,
+//GO(gst_encoding_container_profile_add_profile,
+//GO(gst_encoding_container_profile_contains_profile,
+//GO(gst_encoding_container_profile_get_profiles,
+GO(gst_encoding_container_profile_get_type, LFv)
+//GO(gst_encoding_container_profile_new,
+//GO(gst_encoding_list_all_targets,
+//GO(gst_encoding_list_available_categories,
+//GO(gst_encoding_profile_copy,
+//GO(gst_encoding_profile_find,
+//GO(gst_encoding_profile_from_discoverer,
+//GO(gst_encoding_profile_get_allow_dynamic_output,
+//GO(gst_encoding_profile_get_description,
+//GO(gst_encoding_profile_get_element_properties,
+//GO(gst_encoding_profile_get_file_extension,
+//GO(gst_encoding_profile_get_format,
+//GO(gst_encoding_profile_get_input_caps,
+//GO(gst_encoding_profile_get_name,
+//GO(gst_encoding_profile_get_presence,
+//GO(gst_encoding_profile_get_preset,
+//GO(gst_encoding_profile_get_preset_name,
+//GO(gst_encoding_profile_get_restriction,
+//GO(gst_encoding_profile_get_single_segment,
+GO(gst_encoding_profile_get_type, LFv)
+//GO(gst_encoding_profile_get_type_nick,
+//GO(gst_encoding_profile_is_enabled,
+//GO(gst_encoding_profile_is_equal,
+//GO(gst_encoding_profile_set_allow_dynamic_output,
+//GO(gst_encoding_profile_set_description,
+//GO(gst_encoding_profile_set_element_properties,
+//GO(gst_encoding_profile_set_enabled,
+//GO(gst_encoding_profile_set_format,
+//GO(gst_encoding_profile_set_name,
+//GO(gst_encoding_profile_set_presence,
+//GO(gst_encoding_profile_set_preset,
+//GO(gst_encoding_profile_set_preset_name,
+//GO(gst_encoding_profile_set_restriction,
+//GO(gst_encoding_profile_set_single_segment,
+//GO(gst_encoding_target_add_profile,
+//GO(gst_encoding_target_get_category,
+//GO(gst_encoding_target_get_description,
+//GO(gst_encoding_target_get_name,
+//GO(gst_encoding_target_get_path,
+//GO(gst_encoding_target_get_profile,
+//GO(gst_encoding_target_get_profiles,
+GO(gst_encoding_target_get_type, LFv)
+//GO(gst_encoding_target_load,
+//GO(gst_encoding_target_load_from_file,
+//GO(gst_encoding_target_new,
+//GO(gst_encoding_target_save,
+//GO(gst_encoding_target_save_to_file,
+//GO(gst_encoding_video_profile_get_pass,
+GO(gst_encoding_video_profile_get_type, LFv)
+//GO(gst_encoding_video_profile_get_variableframerate,
+//GO(gst_encoding_video_profile_new,
+//GO(gst_encoding_video_profile_set_pass,
+//GO(gst_encoding_video_profile_set_variableframerate,
+//GO(gst_install_plugins_async,
+//GO(gst_install_plugins_context_copy,
+//GO(gst_install_plugins_context_free,
+GO(gst_install_plugins_context_get_type, LFv)
+//GO(gst_install_plugins_context_new,
+//GO(gst_install_plugins_context_set_confirm_search,
+//GO(gst_install_plugins_context_set_desktop_id,
+//GO(gst_install_plugins_context_set_startup_notification_id,
+//GO(gst_install_plugins_context_set_xid,
+//GO(gst_install_plugins_installation_in_progress,
+//GO(gst_install_plugins_return_get_name,
+GO(gst_install_plugins_return_get_type, LFv)
+//GO(gst_install_plugins_supported,
+//GO(gst_install_plugins_sync,
+//GO(gst_is_missing_plugin_message,
+//GO(gst_missing_decoder_installer_detail_new,
+//GO(gst_missing_decoder_message_new,
+//GO(gst_missing_element_installer_detail_new,
+//GO(gst_missing_element_message_new,
+//GO(gst_missing_encoder_installer_detail_new,
+//GO(gst_missing_encoder_message_new,
+//GO(gst_missing_plugin_message_get_description,
+//GO(gst_missing_plugin_message_get_installer_detail,
+//GO(gst_missing_uri_sink_installer_detail_new,
+//GO(gst_missing_uri_sink_message_new,
+//GO(gst_missing_uri_source_installer_detail_new,
+//GO(gst_missing_uri_source_message_new,
+GO(gst_pb_utils_add_codec_description_to_tag_list, iFppp)
+GO(gst_pb_utils_caps_description_flags_get_type, LFv)
+//GO(gst_pb_utils_get_caps_description_flags,
+GO(gst_pb_utils_get_codec_description, pFp)
+//GO(gst_pb_utils_get_decoder_description,
+//GO(gst_pb_utils_get_element_description,
+//GO(gst_pb_utils_get_encoder_description,
+//GO(gst_pb_utils_get_file_extension_from_caps,
+//GO(gst_pb_utils_get_sink_description,
+//GO(gst_pb_utils_get_source_description,
+GO(gst_pb_utils_init, vFv)
+//GO(gst_plugins_base_version,
+//GO(gst_plugins_base_version_string,
diff --git a/src/wrapped/wrappedgstreamer.c b/src/wrapped/wrappedgstreamer.c
index 8a27986..9583143 100644
--- a/src/wrapped/wrappedgstreamer.c
+++ b/src/wrapped/wrappedgstreamer.c
@@ -1,8 +1,9 @@
+#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
+#include <dirent.h>
#include "wrappedlibs.h"
@@ -18,10 +19,16 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
#include "gtkclass.h"
+#include "fileutils.h"
-const char* gstreamerName = "libgstreamer-1.0.so.0";
+#ifdef ANDROID
+ const char* gstreamerName = "libgstreamer-1.0.so";
+#else
+ const char* gstreamerName = "libgstreamer-1.0.so.0";
+#endif
#define LIBNAME gstreamer
+typedef void (*vFv_t)();
typedef void* (*pFppA_t)(void*, void*, va_list);
typedef void* (*pFv_t)();
typedef size_t (*LFv_t)();
@@ -29,15 +36,48 @@ typedef void* (*pFp_t)(void*);
typedef void (*vFpp_t)(void*, void*);
typedef int (*iFpp_t)(void*, void*);
+void* my_dlopen(x64emu_t* emu, void *filename, int flag);
+int my_dlclose(x64emu_t* emu, void *handle);
+void* my_dlsym(x64emu_t* emu, void *handle, void *symbol);
+
+#ifndef MAX_PATH
+#define MAX_PATH 4096
+#endif
+
#define ADDED_FUNCTIONS() \
GO(gst_object_get_type, LFv_t) \
GO(gst_allocator_get_type, LFv_t) \
GO(gst_task_pool_get_type, LFv_t) \
- GO(gst_structure_new_valist, pFppA_t) \
+ GO(gst_element_get_type, LFv_t) \
+ GO(gst_bin_get_type, LFv_t) \
+ GO(gst_pad_get_type, LFv_t) \
+ GO(gst_uri_handler_get_type, LFv_t) \
GO(gst_structure_new_empty, pFp_t) \
GO(gst_caps_new_empty, pFv_t) \
GO(gst_caps_replace, iFpp_t) \
GO(gst_caps_append_structure, vFpp_t) \
+ GO(gst_bin_add, iFpp_t) \
+ GO(gst_element_link, iFpp_t) \
+
+typedef struct my_gst_plugin_s {
+ void* handle;
+ int is_native;
+} my_gst_plugin_t;
+
+#define ADDED_STRUCT() \
+ int plugin_cnt; \
+ int plugin_cap; \
+ my_gst_plugin_t* plugins; \
+
+#define ADDED_FINI() \
+ for(int i=0; i<my->plugin_cnt; ++i) { \
+ if(my->plugins[i].is_native) \
+ dlclose(my->plugins[i].handle); \
+ else \
+ my_dlclose(thread_get_emu(), my->plugins[i].handle); \
+ } \
+ if(my->plugins) box_free(my->plugins); \
+
#include "generated/wrappedgstreamertypes.h"
@@ -48,6 +88,15 @@ GO(0) \
GO(1) \
GO(2) \
GO(3) \
+GO(4) \
+GO(5) \
+GO(6) \
+GO(7) \
+GO(8) \
+GO(9) \
+GO(10) \
+GO(11) \
+GO(12) \
// GDestroyFunc ...
#define GO(A) \
@@ -207,6 +256,27 @@ static void* findGstBusSyncHandlerFct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstBusSyncHandler callback\n");
return NULL;
}
+//GstBusFunc
+#define GO(A) \
+static uintptr_t my_GstBusFunc_fct_##A = 0; \
+static int my_GstBusFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstBusFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstBusFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GstBusFunc_fct_##A == (uintptr_t)fct) return my_GstBusFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstBusFunc_fct_##A == 0) {my_GstBusFunc_fct_##A = (uintptr_t)fct; return my_GstBusFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstBusFunc callback\n");
+ return NULL;
+}
//GstPluginFeatureFilter
#define GO(A) \
@@ -251,6 +321,272 @@ static void* findGstCapsFilterMapFuncFct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstCapsFilterMapFunc callback\n");
return NULL;
}
+//GstPluginInit
+#define GO(A) \
+static uintptr_t my_GstPluginInit_fct_##A = 0; \
+static int my_GstPluginInit_##A(void* a) \
+{ \
+ return (int)RunFunctionFmt(my_GstPluginInit_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGstPluginInitFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GstPluginInit_fct_##A == (uintptr_t)fct) return my_GstPluginInit_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstPluginInit_fct_##A == 0) {my_GstPluginInit_fct_##A = (uintptr_t)fct; return my_GstPluginInit_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstPluginInit callback\n");
+ return NULL;
+}
+//GstIteratorFoldFunction
+#define GO(A) \
+static uintptr_t my_GstIteratorFoldFunction_fct_##A = 0; \
+static int my_GstIteratorFoldFunction_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstIteratorFoldFunction_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstIteratorFoldFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GstIteratorFoldFunction_fct_##A == (uintptr_t)fct) return my_GstIteratorFoldFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstIteratorFoldFunction_fct_##A == 0) {my_GstIteratorFoldFunction_fct_##A = (uintptr_t)fct; return my_GstIteratorFoldFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstIteratorFoldFunction callback\n");
+ return NULL;
+}
+//GCompareDataFunc
+#define GO(A) \
+static uintptr_t my_GCompareDataFunc_fct_##A = 0; \
+static int my_GCompareDataFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GCompareDataFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGCompareDataFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GCompareDataFunc_fct_##A == (uintptr_t)fct) return my_GCompareDataFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GCompareDataFunc_fct_##A == 0) {my_GCompareDataFunc_fct_##A = (uintptr_t)fct; return my_GCompareDataFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GCompareDataFunc callback\n");
+ return NULL;
+}
+//GstTaskFunction
+#define GO(A) \
+static uintptr_t my_GstTaskFunction_fct_##A = 0; \
+static void my_GstTaskFunction_##A(void* a) \
+{ \
+ RunFunctionFmt(my_GstTaskFunction_fct_##A, "p", a); \
+}
+SUPER()
+#undef GO
+static void* findGstTaskFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GstTaskFunction_fct_##A == (uintptr_t)fct) return my_GstTaskFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstTaskFunction_fct_##A == 0) {my_GstTaskFunction_fct_##A = (uintptr_t)fct; return my_GstTaskFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstTaskFunction callback\n");
+ return NULL;
+}
+//GstTagForeachFunc
+#define GO(A) \
+static uintptr_t my_GstTagForeachFunc_fct_##A = 0; \
+static void my_GstTagForeachFunc_##A(void* a, void* b, void* c) \
+{ \
+ RunFunctionFmt(my_GstTagForeachFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstTagForeachFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ #define GO(A) if(my_GstTagForeachFunc_fct_##A == (uintptr_t)fct) return my_GstTagForeachFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstTagForeachFunc_fct_##A == 0) {my_GstTagForeachFunc_fct_##A = (uintptr_t)fct; return my_GstTagForeachFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstTagForeachFunc callback\n");
+ return NULL;
+}
+//GstPadActivateFunction
+#define GO(A) \
+static uintptr_t my_GstPadActivateFunction_fct_##A = 0; \
+static int my_GstPadActivateFunction_##A(void* a, void* b) \
+{ \
+ return (int)RunFunctionFmt(my_GstPadActivateFunction_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* findGstPadActivateFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstPadActivateFunction_fct_##A == (uintptr_t)fct) return my_GstPadActivateFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstPadActivateFunction_fct_##A == 0) {my_GstPadActivateFunction_fct_##A = (uintptr_t)fct; return my_GstPadActivateFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstPadActivateFunction callback\n");
+ return NULL;
+}
+//GstPadProbeCallback
+#define GO(A) \
+static uintptr_t my_GstPadProbeCallback_fct_##A = 0; \
+static int my_GstPadProbeCallback_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstPadProbeCallback_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstPadProbeCallbackFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstPadProbeCallback_fct_##A == (uintptr_t)fct) return my_GstPadProbeCallback_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstPadProbeCallback_fct_##A == 0) {my_GstPadProbeCallback_fct_##A = (uintptr_t)fct; return my_GstPadProbeCallback_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstPadProbeCallback callback\n");
+ return NULL;
+}
+//GstStructureForeachFunc
+#define GO(A) \
+static uintptr_t my_GstStructureForeachFunc_fct_##A = 0; \
+static int my_GstStructureForeachFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstStructureForeachFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstStructureForeachFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstStructureForeachFunc_fct_##A == (uintptr_t)fct) return my_GstStructureForeachFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstStructureForeachFunc_fct_##A == 0) {my_GstStructureForeachFunc_fct_##A = (uintptr_t)fct; return my_GstStructureForeachFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstStructureForeachFunc callback\n");
+ return NULL;
+}
+//GstPadLinkFunction
+#define GO(A) \
+static uintptr_t my_GstPadLinkFunction_fct_##A = 0; \
+static int my_GstPadLinkFunction_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstPadLinkFunction_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstPadLinkFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstPadLinkFunction_fct_##A == (uintptr_t)fct) return my_GstPadLinkFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstPadLinkFunction_fct_##A == 0) {my_GstPadLinkFunction_fct_##A = (uintptr_t)fct; return my_GstPadLinkFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstPadLinkFunction callback\n");
+ return NULL;
+}
+//GstStructureFilterMapFunc
+#define GO(A) \
+static uintptr_t my_GstStructureFilterMapFunc_fct_##A = 0; \
+static int my_GstStructureFilterMapFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstStructureFilterMapFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstStructureFilterMapFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstStructureFilterMapFunc_fct_##A == (uintptr_t)fct) return my_GstStructureFilterMapFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstStructureFilterMapFunc_fct_##A == 0) {my_GstStructureFilterMapFunc_fct_##A = (uintptr_t)fct; return my_GstStructureFilterMapFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstStructureFilterMapFunc callback\n");
+ return NULL;
+}
+//GstElementForeachPadFunc
+#define GO(A) \
+static uintptr_t my_GstElementForeachPadFunc_fct_##A = 0; \
+static int my_GstElementForeachPadFunc_##A(void* a, void* b, void* c) \
+{ \
+ return (int)RunFunctionFmt(my_GstElementForeachPadFunc_fct_##A, "ppp", a, b, c); \
+}
+SUPER()
+#undef GO
+static void* findGstElementForeachPadFuncFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstElementForeachPadFunc_fct_##A == (uintptr_t)fct) return my_GstElementForeachPadFunc_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstElementForeachPadFunc_fct_##A == 0) {my_GstElementForeachPadFunc_fct_##A = (uintptr_t)fct; return my_GstElementForeachPadFunc_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstElementForeachPadFunc callback\n");
+ return NULL;
+}
+//GstTypeFindFunction
+#define GO(A) \
+static uintptr_t my_GstTypeFindFunction_fct_##A = 0; \
+static void my_GstTypeFindFunction_##A(void* a, void* b) \
+{ \
+ RunFunctionFmt(my_GstTypeFindFunction_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* findGstTypeFindFunctionFct(void* fct)
+{
+ if(!fct) return fct;
+ void* p;
+ if((p = GetNativeFnc((uintptr_t)fct))) return p;
+ #define GO(A) if(my_GstTypeFindFunction_fct_##A == (uintptr_t)fct) return my_GstTypeFindFunction_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_GstTypeFindFunction_fct_##A == 0) {my_GstTypeFindFunction_fct_##A = (uintptr_t)fct; return my_GstTypeFindFunction_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for gstreamer GstTypeFindFunction callback\n");
+ return NULL;
+}
#undef SUPER
@@ -390,16 +726,361 @@ EXPORT int my_gst_caps_foreach(x64emu_t* emu, void* caps, void* f, void* data)
return my->gst_caps_foreach(caps, findGstCapsFilterMapFuncFct(f), data);
}
+EXPORT uint32_t my_gst_bus_add_watch(x64emu_t* emu, void* bus, void* f, void* data)
+{
+ return my->gst_bus_add_watch(bus, findGstBusFuncFct(f), data);
+}
+
+EXPORT uint32_t my_gst_bus_add_watch_full(x64emu_t* emu, void* bus, int priority, void* f, void* data, void* d)
+{
+ return my->gst_bus_add_watch_full(bus, priority, findGstBusFuncFct(f), data, findDestroyFct(d));
+}
+
+EXPORT int my_gst_bin_add_many(x64emu_t* emu, void* bin, void* first, void** b)
+{
+ int ret = my->gst_bin_add(bin, first);
+ while(ret && *b) {
+ ret = my->gst_bin_add(bin, *b);
+ ++b;
+ }
+ return ret;
+}
+
+EXPORT int my_gst_element_link_many(x64emu_t* emu, void* e1, void* e2, void** b)
+{
+ int ret = my->gst_element_link(e1, e2);
+ void* a = e2;
+ while(ret && *b) {
+ ret = my->gst_element_link(a, *b);
+ a = *b;
+ ++b;
+ }
+ return ret;
+}
+
+EXPORT void* my_gst_plugin_load_file(x64emu_t* emu, const char* filename, void** error)
+{
+ printf_log(LOG_INFO, "using gst_plugin_load_file, file %s (is x86_64=%d)\n", filename, FileIsX64ELF(filename));
+ return my->gst_plugin_load_file((void*)filename, error);
+}
+
+static void register_plugins_from_folder(x64emu_t* emu, const char* folder)
+{
+ if(!folder) {
+ printf_log(/*LOG_DEBUG*/LOG_INFO, "BOX64 didn't detect any custom gstreamer-1.0 folder");
+ return;
+ }
+ DIR *d;
+ struct dirent *dir;
+ // get folder where gstreamer came from
+ char native_folder[MAX_PATH+1] = {0};
+ Dl_info dli;
+ if(dladdr(my->gst_init_check, &dli)) {
+ strcpy(native_folder, dli.dli_fname);
+ char* p = strrchr(native_folder, '/');
+ *p = '\0';
+ strcat(native_folder, "/gstreamer-1.0/");
+ printf_log(/*LOG_DEBUG*/LOG_INFO, "BOX64 Will look for native gstreamer plugin in %s", native_folder);
+ }
+ d = opendir(folder);
+ if(!d)
+ return;
+ while((dir = readdir(d)) != NULL) {
+ if(strstr(dir->d_name, "libgst")==dir->d_name && strstr(dir->d_name, ".so")) {
+ // handling this one, stripping to get the plugin name
+ char name[500];
+ int is_native = 0;
+ void* handle = NULL;
+ char filename[MAX_PATH];
+ char regfunc_name[500];
+ // get the name of the function
+ strcpy(name, dir->d_name + strlen("libgst"));
+ *strrchr(name, '.') = '\0';
+ snprintf(regfunc_name, sizeof(regfunc_name), "gst_plugin_%s_register", name);
+ // check if native version exist
+ if(native_folder[0]) {
+ strcpy(filename, native_folder);
+ strcat(filename, dir->d_name);
+ handle = dlopen(filename, 2);
+ }
+ if(handle)
+ is_native = 1;
+ else {
+ strcpy(filename, folder);
+ strcat(filename, "/");
+ strcat(filename, dir->d_name);
+ handle = my_dlopen(emu, filename, 2);
+ }
+ void* f_init = handle?(is_native?dlsym(handle, regfunc_name):my_dlsym(emu, handle, regfunc_name)):NULL;
+ if(f_init) {
+ printf_log(LOG_DEBUG, "BOX64: Will registering %sgstplugin %s\n", is_native?"native ":"", filename);
+ if(is_native)
+ ((vFv_t)(f_init))();
+ else
+ RunFunctionFmt((uintptr_t)f_init, "");
+ if(my->plugin_cnt==my->plugin_cap) {
+ my->plugin_cap += 8;
+ my->plugins = (my_gst_plugin_t*)box_realloc(my->plugins, my->plugin_cap*sizeof(my_gst_plugin_t));
+ }
+ my->plugins[my->plugin_cnt].is_native = is_native;
+ my->plugins[my->plugin_cnt++].handle = handle;
+ } else {
+ printf_log(LOG_DEBUG, "BOX64: Failled to register %sgstplugin %s, name=%s, handle=%p\n", is_native?"native ":"", filename, name, handle);
+ }
+ if(handle && !f_init) {
+ is_native?dlclose(handle):my_dlclose(emu, handle);
+ handle = NULL;
+ }
+ }
+ }
+ closedir(d);
+}
+
+extern const char* box64_custom_gstreamer;
+EXPORT int my_gst_init_check(x64emu_t* emu, int* argc, char*** argv, void** error)
+{
+ int ret = my->gst_init_check(argc, argv, error);
+ register_plugins_from_folder(emu, box64_custom_gstreamer);
+ return ret;
+}
+
+EXPORT void my_gst_init(x64emu_t* emu, int* argc, char*** argv)
+{
+ my->gst_init(argc, argv);
+ register_plugins_from_folder(emu, box64_custom_gstreamer);
+}
+
+EXPORT int my_gst_plugin_register_static(x64emu_t* emu, int maj_v, int min_v, void* name, void* desc, void* init_f, void* ver, void* lic, void* source, void* pack, void* orig)
+{
+ return my->gst_plugin_register_static(maj_v, min_v, name, desc, findGstPluginInitFct(init_f), ver, lic, source, pack, orig);
+}
+
+EXPORT int my_gst_info_vasprintf(x64emu_t* emu, void* res, void* fmt, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ return my->gst_info_vasprintf(res, fmt, VARARGS);
+}
+
+EXPORT void* my__gst_element_error_printf(x64emu_t* emu, void* fmt, uintptr_t* b)
+{
+ char* buffer;
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 1);
+ int len = my->gst_info_vasprintf(&buffer, fmt, VARARGS);
+ if(len<0)
+ buffer = NULL;
+ return buffer;
+}
+
+EXPORT void my_gst_structure_set_valist(x64emu_t* emu, void* st, void* fieldname, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ my->gst_structure_set_valist(st, fieldname, VARARGS);
+}
+
+EXPORT void my_gst_structure_set(x64emu_t* emu, void* st, void* fieldname, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 2);
+ my->gst_structure_set_valist(st, fieldname, VARARGS);
+}
+
+EXPORT int my_gst_iterator_fold(x64emu_t* emu, void* it, void* f, void* ret, void* data)
+{
+ return my->gst_iterator_fold(it, findGstIteratorFoldFunctionFct(f), ret, data);
+}
+
+EXPORT void* my_gst_util_array_binary_search(x64emu_t* emu, void* array, uint32_t num, size_t size, void* f, int mode, void* search, void* data)
+{
+ return my->gst_util_array_binary_search(array, num, size, findGCompareDataFuncFct(f), mode, search, data);
+}
+
+EXPORT void* my_gst_structure_new_valist(x64emu_t* emu, void* name, void* first, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ my->gst_structure_new_valist(name, first, VARARGS);
+}
+
+EXPORT void* my_gst_make_element_message_details(x64emu_t* emu, void* name, uintptr_t* b)
+{
+ if(!name)
+ return NULL;
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 1);
+ my->gst_structure_new_valist("detail", name, VARARGS);
+}
+
+EXPORT int my_gst_pad_start_task(x64emu_t* emu, void* pad, void* f, void* data, void* d)
+{
+ return my->gst_pad_start_task(pad, findGstTaskFunctionFct(f), data, findDestroyFct(d));
+}
+
+EXPORT void my_gst_tag_list_foreach(x64emu_t* emu, void* list, void* f, void* data)
+{
+ my->gst_tag_list_foreach(list, findGstTagForeachFuncFct(f), data);
+}
+
+EXPORT void* my_gst_memory_new_wrapped(x64emu_t* emu, int flags, void* data, size_t maxsz, size_t offset, size_t size, void* user_data, void* d)
+{
+ return my->gst_memory_new_wrapped(flags, data, maxsz, offset, size, user_data, findDestroyFct(d));
+}
+
+EXPORT void* my_gst_pad_create_stream_id_printf_valist(x64emu_t* emu, void* pad, void* parent, void* id, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ return my->gst_pad_create_stream_id_printf_valist(pad, parent, id, VARARGS);
+}
+
+EXPORT void* my_gst_pad_create_stream_id_printf(x64emu_t* emu, void* pad, void* parent, void* id, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 3);
+ return my->gst_pad_create_stream_id_printf_valist(pad, parent, id, VARARGS);
+}
+
+EXPORT void my_gst_pad_set_activate_function_full(x64emu_t* emu, void* pad, void* f, void* data, void* d)
+{
+ my->gst_pad_set_activate_function_full(pad, findGstPadActivateFunctionFct(f), data, findDestroyFct(d));
+}
+
+EXPORT void my_gst_tag_list_add_valist(x64emu_t* emu, void* list, int mode, void* tag, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ my->gst_tag_list_add_valist(list, mode, tag, VARARGS);
+}
+EXPORT void my_gst_tag_list_add(x64emu_t* emu, void* list, int mode, void* tag, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 3);
+ my->gst_tag_list_add_valist(list, mode, tag, VARARGS);
+}
+
+EXPORT void* my_gst_tag_list_new_valist(x64emu_t* emu, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ return my->gst_tag_list_new_valist(VARARGS);
+}
+
+EXPORT void* my_gst_tag_list_new(x64emu_t* emu, void* arg, uintptr_t* b)
+{
+ // construct VARARGS with arg[0] too, because gst_tag_list_new_valist have just the va_list
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 0);
+ return my->gst_tag_list_new_valist(VARARGS);
+}
+
+EXPORT void* my_gst_caps_features_new_valist(x64emu_t* emu, void* feat1, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ return my->gst_caps_features_new_valist(feat1, VARARGS);
+}
+
+EXPORT void* my_gst_caps_features_new(x64emu_t* emu, void* feat1, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 1);
+ return my->gst_caps_features_new_valist(feat1, VARARGS);
+}
+
+EXPORT unsigned long my_gst_pad_add_probe(x64emu_t* emu, void* pad, int mask, void* f, void* data, void* d)
+{
+ return my->gst_pad_add_probe(pad, mask, findGstPadProbeCallbackFct(f), data, findDestroyFct(d));
+}
+
+EXPORT int my_gst_structure_foreach(x64emu_t* emu, void* st, void* f, void* data)
+{
+ return my->gst_structure_foreach(st, findGstStructureForeachFuncFct(f), data);
+}
+
+EXPORT void my_gst_pad_set_link_function_full(x64emu_t* emu, void* pad, void* f, void* data, void *d)
+{
+ my->gst_pad_set_link_function_full(pad, findGstPadLinkFunctionFct(f), data, findDestroyFct(d));
+}
+
+EXPORT void my_gst_tag_list_add_valist_values(x64emu_t* emu, void* list, int mode, void* tag, x64_va_list_t V)
+{
+ #ifdef CONVERT_VALIST
+ CONVERT_VALIST(V);
+ #else
+ CREATE_VALIST_FROM_VALIST(V, emu->scratch);
+ #endif
+ my->gst_tag_list_add_valist_values(list, mode, tag, VARARGS);
+}
+
+EXPORT void my_gst_tag_list_add_values(x64emu_t* emu, void* list, int mode, void* tag, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 3);
+ my->gst_tag_list_add_valist_values(list, mode, tag, VARARGS);
+}
+
+EXPORT void my_gst_structure_filter_and_map_in_place(x64emu_t* emu, void* s, void* f, void* data)
+{
+ my->gst_structure_filter_and_map_in_place(s, findGstStructureFilterMapFuncFct(f), data);
+}
+
+EXPORT int my_gst_element_foreach_sink_pad(x64emu_t* emu, void* element, void* f, void* data)
+{
+ return my->gst_element_foreach_sink_pad(element, findGstElementForeachPadFuncFct(f),data);
+}
+
+EXPORT void* my_gst_task_new(x64emu_t* emu, void* f, void* data, void* d)
+{
+ return my->gst_task_new(findGstTaskFunctionFct(f), data, findDestroyFct(d));
+}
+
+EXPORT int my_gst_type_find_register(x64emu_t* emu, void* plugin, void* name, uint32_t rank, void* f, void* ext, void* caps, void* data, void* d)
+{
+ return my->gst_type_find_register(plugin, name, rank, findGstTypeFindFunctionFct(f), ext, caps, data, findDestroyFct(f));
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
-#define CUSTOM_INIT \
- getMy(lib); \
- SetGstObjectID(my->gst_object_get_type()); \
- SetGstAllocatorID(my->gst_allocator_get_type()); \
- SetGstTaskPoolID(my->gst_task_pool_get_type()); \
- setNeededLibs(lib, 1, "libgtk-3.so.0");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstObjectID(my->gst_object_get_type()); \
+ SetGstAllocatorID(my->gst_allocator_get_type()); \
+ SetGstTaskPoolID(my->gst_task_pool_get_type()); \
+ SetGstElementID(my->gst_element_get_type()); \
+ SetGstBinID(my->gst_bin_get_type()); \
+ SetGstPadID(my->gst_pad_get_type()); \
+ SetGstURIHandlerID(my->gst_uri_handler_get_type()); \
+ setNeededLibs(lib, 1, "libgtk-3.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstObjectID(my->gst_object_get_type()); \
+ SetGstAllocatorID(my->gst_allocator_get_type()); \
+ SetGstTaskPoolID(my->gst_task_pool_get_type()); \
+ SetGstElementID(my->gst_element_get_type()); \
+ SetGstBinID(my->gst_bin_get_type()); \
+ SetGstPadID(my->gst_pad_get_type()); \
+ SetGstURIHandlerID(my->gst_uri_handler_get_type()); \
+ setNeededLibs(lib, 1, "libgtk-3.so.0");
+#endif
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedgstreamer_private.h b/src/wrapped/wrappedgstreamer_private.h
index 696de89..bf436cc 100644
--- a/src/wrapped/wrappedgstreamer_private.h
+++ b/src/wrapped/wrappedgstreamer_private.h
@@ -5,12 +5,12 @@
GO(gst_allocation_params_copy, pFp)
//GO(gst_allocation_params_free,
//GO(gst_allocation_params_get_type,
-//GO(gst_allocation_params_init,
+GO(gst_allocation_params_init, vFp)
GO(gst_allocator_alloc, pFpLp)
-//GO(gst_allocator_find,
+GO(gst_allocator_find, pFp)
//GO(gst_allocator_flags_get_type,
//GO(gst_allocator_free,
-GO(gst_allocator_get_type, pFv)
+GO(gst_allocator_get_type, LFv)
//GO(gst_allocator_register,
//GO(gst_allocator_set_default,
//GO(gst_atomic_queue_get_type,
@@ -22,14 +22,14 @@ GO(gst_atomic_queue_push, vFpp)
GO(gst_atomic_queue_ref, vFp)
GO(gst_atomic_queue_unref, vFp)
GO(gst_bin_add, iFpp)
-//GOM(gst_bin_add_many, vFppV)
+GOM(gst_bin_add_many, vFEppV)
GO(gst_bin_find_unlinked_pad, pFpi)
-GO(gst_bin_flags_get_type, pFv)
+GO(gst_bin_flags_get_type, LFv)
GO(gst_bin_get_by_interface, pFpL)
GO(gst_bin_get_by_name, pFpp)
GO(gst_bin_get_by_name_recurse_up, pFpp)
GO(gst_bin_get_suppressed_flags, uFp)
-GO(gst_bin_get_type, pFv)
+GO(gst_bin_get_type, LFv)
GO(gst_bin_iterate_all_by_element_factory_name, pFpp)
GO(gst_bin_iterate_all_by_interface, pFpp)
GO(gst_bin_iterate_elements, pFp)
@@ -43,7 +43,7 @@ GO(gst_bin_remove, iFpp)
//GOM(gst_bin_remove_many, iFEppV)
GO(gst_bin_set_suppressed_flags, vFpu)
GO(gst_bin_sync_children_states, iFp)
-GO(gst_bitmask_get_type, pFv)
+GO(gst_bitmask_get_type, LFv)
DATAB(_gst_bitmask_type, sizeof(void*))
GO(gst_buffer_add_meta, pFppp)
GO(gst_buffer_add_parent_buffer_meta, pFpp)
@@ -54,14 +54,14 @@ GO(gst_buffer_append_memory, vFpp)
GO(gst_buffer_append_region, pFppll)
GO(gst_buffer_copy, pFp)
GO(gst_buffer_copy_deep, pFp)
-GO(gst_buffer_copy_flags_get_type, pFv)
+GO(gst_buffer_copy_flags_get_type, LFv)
GO(gst_buffer_copy_into, iFppiLL)
GO(gst_buffer_copy_region, pFpiLL)
GO(gst_buffer_extract, LFpLpL)
GO(gst_buffer_extract_dup, vFpLLpp)
GO(gst_buffer_fill, LFpLpL)
GO(gst_buffer_find_memory, iFpLLppp)
-GO(gst_buffer_flags_get_type, pFv)
+GO(gst_buffer_flags_get_type, LFv)
//GOM(gst_buffer_foreach_meta, iFEpBp)
GO(gst_buffer_get_all_memory, pFp)
GO(gst_buffer_get_flags, iFp)
@@ -74,9 +74,9 @@ GO(gst_buffer_get_reference_timestamp_meta, pFpp)
GO(gst_buffer_get_size, LFp)
GO(gst_buffer_get_sizes, LFppp)
GO(gst_buffer_get_sizes_range, LFpuipp)
-GO(gst_buffer_get_type, pFv)
+GO(gst_buffer_get_type, LFv)
GO(gst_buffer_has_flags, iFpi)
-GO(gst_buffering_mode_get_type, pFv)
+GO(gst_buffering_mode_get_type, LFv)
GO(gst_buffer_insert_memory, vFpip)
GO(gst_buffer_is_all_memory_writable, iFp)
GO(gst_buffer_is_memory_range_writable, iFpui)
@@ -86,10 +86,10 @@ GO(gst_buffer_list_calculate_size, LFp)
//GO(gst_buffer_list_copy,
GO(gst_buffer_list_copy_deep, pFp)
//GO(gst_buffer_list_foreach,
-//GO(gst_buffer_list_get,
+GO(gst_buffer_list_get, pFpu)
//GO(gst_buffer_list_get_type,
//GO(gst_buffer_list_get_writable,
-//GO(gst_buffer_list_insert,
+GO(gst_buffer_list_insert, vFpip)
GO(gst_buffer_list_length, uFp)
GO(gst_buffer_list_new, pFv)
GO(gst_buffer_list_new_sized, pFu)
@@ -105,6 +105,7 @@ GO(gst_buffer_memcmp, iFpLpL)
GO(gst_buffer_memset, LFpLCL)
GO(gst_buffer_new, pFv)
GO(gst_buffer_new_allocate, pFplp)
+GO(gst_buffer_new_memdup, pFpL)
GO(gst_buffer_new_wrapped, pFpl)
GO(gst_buffer_new_wrapped_bytes, pFp)
GOM(gst_buffer_new_wrapped_full, pFEiplllpp)
@@ -120,10 +121,10 @@ GO(gst_buffer_pool_config_has_option, iFpp)
GO(gst_buffer_pool_config_n_options, uFp)
GO(gst_buffer_pool_config_set_allocator, vFppp)
GO(gst_buffer_pool_config_set_params, vFppuuu)
-//GO(gst_buffer_pool_config_validate_params,
+GO(gst_buffer_pool_config_validate_params, iFppuuu)
GO(gst_buffer_pool_get_config, pFp)
GO(gst_buffer_pool_get_options, pFp)
-//GO(gst_buffer_pool_get_type,
+GO(gst_buffer_pool_get_type, LFv)
GO(gst_buffer_pool_has_option, iFpp)
GO(gst_buffer_pool_is_active, iFp)
GO(gst_buffer_pool_new, pFv)
@@ -151,15 +152,15 @@ GO(gst_buffer_unref, vFp)
GO(gst_buffer_unset_flags, iFpi)
GO(gst_bus_add_signal_watch, vFp)
GO(gst_bus_add_signal_watch_full, vFpi)
-//GOM(gst_bus_add_watch, uFEpBp)
-//GOM(gst_bus_add_watch_full, iFEpiBpB)
+GOM(gst_bus_add_watch, uFEppp)
+GOM(gst_bus_add_watch_full, uFEpippp)
GO(gst_bus_async_signal_func, iFppp)
GO(gst_bus_create_watch, pFp)
GO(gst_bus_disable_sync_message_emission, vFp)
GO(gst_bus_enable_sync_message_emission, vFp)
-GO(gst_bus_flags_get_type, pFv)
+GO(gst_bus_flags_get_type, LFv)
GO(gst_bus_get_pollfd, vFpp)
-GO(gst_bus_get_type, pFv)
+GO(gst_bus_get_type, LFv)
GO(gst_bus_have_pending, iFp)
GO(gst_bus_new, pFv)
GO(gst_bus_peek, pFp)
@@ -171,25 +172,25 @@ GO(gst_bus_remove_signal_watch, vFp)
GO(gst_bus_remove_watch, iFp)
GO(gst_bus_set_flushing, vFpi)
GOM(gst_bus_set_sync_handler, vFEpppp)
-GO(gst_bus_sync_reply_get_type, pFv)
+GO(gst_bus_sync_reply_get_type, LFv)
GO(gst_bus_sync_signal_handler, iFppp)
GO(gst_bus_timed_pop, pFpU)
GO(gst_bus_timed_pop_filtered, pFpUi)
GO(gst_calculate_linear_regression, iFppuppppp)
-//DATAB(_gst_caps_any,
+DATAB(_gst_caps_any, sizeof(void*))
GO(gst_caps_append, vFpp)
GO(gst_caps_append_structure, vFpp)
GO(gst_caps_append_structure_full, vFppp)
GO(gst_caps_can_intersect, iFpp)
GO(gst_caps_copy, pFp)
GO(gst_caps_copy_nth, pFpu)
-//GOM(gst_caps_features_add, vFEpBp)
+GO(gst_caps_features_add, vFpp)
//GO(gst_caps_features_add_id,
//DATAB(_gst_caps_features_any,
GO(gst_caps_features_contains, iFpp)
GO(gst_caps_features_contains_id, iFpu)
GO(gst_caps_features_copy, pFp)
-//GO(gst_caps_features_free,
+GO(gst_caps_features_free, vFp)
GO(gst_caps_features_from_string, pFp)
GO(gst_caps_features_get_nth, pFpu)
GO(gst_caps_features_get_nth_id, uFpu)
@@ -197,13 +198,13 @@ GO(gst_caps_features_get_size, uFp)
//GO(gst_caps_features_get_type,
GO(gst_caps_features_is_any, iFp)
GO(gst_caps_features_is_equal, iFpp)
-//DATAB(_gst_caps_features_memory_system_memory,
-//GO(gst_caps_features_new,
+DATAB(_gst_caps_features_memory_system_memory, sizeof(void*))
+GOM(gst_caps_features_new, pFEpV)
GO(gst_caps_features_new_any, pFv)
//GO(gst_caps_features_new_empty,
//GO(gst_caps_features_new_id,
GO(gst_caps_features_new_id_valist, pFup)
-GO(gst_caps_features_new_valist, pFpp)
+GOM(gst_caps_features_new_valist, pFEpA)
GO(gst_caps_features_remove, vFpp)
GO(gst_caps_features_remove_id, vFpu)
GO(gst_caps_features_set_parent_refcount, iFpp)
@@ -211,16 +212,16 @@ GO(gst_caps_features_to_string, pFp)
//DATAB(_gst_caps_features_type,
//GO(gst_caps_filter_and_map_in_place,
GO(gst_caps_fixate, pFp)
-GO(gst_caps_flags_get_type, pFv)
+GO(gst_caps_flags_get_type, LFv)
GOM(gst_caps_foreach, iFEppp)
GO(gst_caps_from_string, pFp)
GO(gst_caps_get_features, pFpu)
GO(gst_caps_get_size, uFp)
GO(gst_caps_get_structure, pFpu)
-GO(gst_caps_get_type, pFv)
+GO(gst_caps_get_type, LFv)
GO(gst_caps_intersect, pFpp)
GO(gst_caps_intersect_full, pFppi)
-GO(gst_caps_intersect_mode_get_type, pFv)
+GO(gst_caps_intersect_mode_get_type, LFv)
GO(gst_caps_is_always_compatible, iFpp)
GO(gst_caps_is_any, iFp)
GO(gst_caps_is_empty, iFp)
@@ -241,7 +242,7 @@ GO(gst_caps_new_empty_simple, pFp)
//GOM(gst_caps_new_full, pFEpV)
//GOM(gst_caps_new_full_valist, pFEpA)
GOM(gst_caps_new_simple, pFEppV)
-//DATAB(_gst_caps_none,
+DATAB(_gst_caps_none, sizeof(void*))
GO(gst_caps_normalize, pFp)
GO(gst_caps_ref, pFp)
GO(gst_caps_remove_structure, vFpp)
@@ -291,14 +292,14 @@ DATAB(GST_CAT_DEFAULT, sizeof(void*))
//DATAB(GST_CAT_SCHEDULING,
//DATAB(GST_CAT_SIGNAL,
//DATAB(GST_CAT_STATES,
-//GO(gst_child_proxy_child_added,
+GO(gst_child_proxy_child_added, vFppp)
GO(gst_child_proxy_child_removed, vFppp)
//GO(gst_child_proxy_get,
GO(gst_child_proxy_get_child_by_index, pFpu)
//GO(gst_child_proxy_get_child_by_name,
GO(gst_child_proxy_get_children_count, uFp)
GO(gst_child_proxy_get_property, vFppp)
-//GO(gst_child_proxy_get_type,
+GO(gst_child_proxy_get_type, LFv)
//GO(gst_child_proxy_get_valist,
GO(gst_child_proxy_lookup, iFpppp)
//GO(gst_child_proxy_set,
@@ -375,7 +376,7 @@ GO(gst_control_binding_sync_values, iFppLL)
//GO(gst_control_source_get_value,
//GO(gst_control_source_get_value_array,
//GO(gst_core_error_get_type,
-//GO(gst_core_error_quark,
+GO(gst_core_error_quark, pFv)
//GO(gst_date_time_get_day,
//GO(gst_date_time_get_hour,
GO(gst_date_time_get_microsecond, iFp)
@@ -407,7 +408,7 @@ GO(gst_date_time_ref, pFp)
GO(gst_date_time_to_g_date_time, pFp)
GO(gst_date_time_to_iso8601_string, pFp)
DATAB(_gst_date_time_type, sizeof(void*))
-//GO(gst_date_time_unref,
+GO(gst_date_time_unref, vFp)
//GO(gst_debug_add_log_function,
GO(gst_debug_add_ring_buffer_logger, vFuu)
GO(gst_debug_bin_to_dot_data, pFpi)
@@ -445,7 +446,7 @@ GOM(gst_debug_log_valist, vFEpippippA)
DATAB(_gst_debug_min, sizeof(int))
//GO(_gst_debug_nameof_funcptr,
//GO(gst_debug_print_stack_trace,
-//GO(_gst_debug_register_funcptr,
+GO(_gst_debug_register_funcptr, vFpp)
//GO(gst_debug_remove_log_function,
GO(gst_debug_remove_log_function_by_data, uFp)
//GO(gst_debug_remove_ring_buffer_logger,
@@ -467,7 +468,7 @@ GO(gst_device_get_properties, pFp)
//GO(gst_device_get_type,
GO(gst_device_has_classes, iFpp)
GO(gst_device_has_classesv, iFpp)
-//GO(gst_device_monitor_add_filter,
+GO(gst_device_monitor_add_filter, uFppp)
GO(gst_device_monitor_get_bus, pFp)
GO(gst_device_monitor_get_devices, pFp)
GO(gst_device_monitor_get_providers, pFp)
@@ -476,7 +477,7 @@ GO(gst_device_monitor_get_show_all_devices, iFp)
GO(gst_device_monitor_new, pFv)
GO(gst_device_monitor_remove_filter, iFpu)
GO(gst_device_monitor_set_show_all_devices, vFpi)
-//GO(gst_device_monitor_start,
+GO(gst_device_monitor_start, iFp)
//GO(gst_device_monitor_stop,
//GO(gst_device_provider_can_monitor,
//GO(gst_device_provider_class_add_metadata,
@@ -533,7 +534,7 @@ GO(gst_element_class_set_metadata, vFppppp)
GO(gst_element_class_set_static_metadata, vFppppp)
GO(gst_element_continue_state, uFpu)
//GOM(gst_element_create_all_pads, iFEpBp)
-//GO(_gst_element_error_printf,
+GOM(_gst_element_error_printf, pFEpV)
GO(gst_element_factory_can_sink_all_caps, iFpp)
GO(gst_element_factory_can_sink_any_caps, iFpp)
GO(gst_element_factory_can_src_all_caps, iFpp)
@@ -545,7 +546,7 @@ GO(gst_element_factory_get_metadata, pFpp)
GO(gst_element_factory_get_metadata_keys, pFp)
GO(gst_element_factory_get_num_pad_templates, uFp)
GO(gst_element_factory_get_static_pad_templates, pFp)
-GO(gst_element_factory_get_type, pFv)
+GO(gst_element_factory_get_type, LFv)
GO(gst_element_factory_get_uri_protocols, pFp)
GO(gst_element_factory_get_uri_type, uFp)
GO(gst_element_factory_has_interface, iFpp)
@@ -553,9 +554,9 @@ GO(gst_element_factory_list_filter, pFppii)
GO(gst_element_factory_list_get_elements, pFLu)
GO(gst_element_factory_list_is_type, iFpL)
GO(gst_element_factory_make, pFpp)
-GO(gst_element_flags_get_type, pFv)
+GO(gst_element_flags_get_type, LFv)
//GOM(gst_element_foreach_pad, iFEpBp)
-//GOM(gst_element_foreach_sink_pad, iFEpBp)
+GOM(gst_element_foreach_sink_pad, iFEppp)
//GOM(gst_element_foreach_src_pad, iFEpBp)
GO(gst_element_get_base_time, UFp)
GO(gst_element_get_bus, pFp)
@@ -575,14 +576,14 @@ GO(gst_element_get_pad_template_list, pFp)
GO(gst_element_get_start_time, UFp)
GO(gst_element_get_state, uFpppL)
GO(gst_element_get_static_pad, pFpp)
-GO(gst_element_get_type, pFv)
+GO(gst_element_get_type, LFv)
GO(gst_element_is_locked_state, iFp)
GO(gst_element_iterate_pads, pFp)
GO(gst_element_iterate_sink_pads, pFp)
GO(gst_element_iterate_src_pads, pFp)
GO(gst_element_link, iFpp)
GO(gst_element_link_filtered, iFppp)
-//GOM(gst_element_link_many, iFEppV)
+GOM(gst_element_link_many, iFEppV)
GO(gst_element_link_pads, iFpppp)
GO(gst_element_link_pads_filtered, iFppppp)
GO(gst_element_link_pads_full, iFppppu)
@@ -624,7 +625,7 @@ GO(gst_event_copy_segment, vFpp)
GO(gst_event_get_running_time_offset, IFp)
GO(gst_event_get_seqnum, uFp)
GO(gst_event_get_structure, pFp)
-GO(gst_event_get_type, pFv)
+GO(gst_event_get_type, LFv)
GO(gst_event_has_name, iFpp)
GO(gst_event_has_name_id, iFpp)
GO(gst_event_new_buffer_size, pFiIIi)
@@ -689,10 +690,10 @@ GO(gst_event_set_stream_flags, vFpi)
GO(gst_event_steal, pFp)
GO(gst_event_take, iFpp)
DATAB(_gst_event_type, sizeof(void*))
-GO(gst_event_type_flags_get_type, pFv)
+GO(gst_event_type_flags_get_type, LFv)
GO(gst_event_type_get_flags, uFu)
GO(gst_event_type_get_name, pFu)
-GO(gst_event_type_get_type, pFv)
+GO(gst_event_type_get_type, LFv)
GO(gst_event_type_to_quark, uFu)
GO(gst_event_unref, vFp)
GO(gst_event_writable_structure, pFp)
@@ -702,48 +703,48 @@ GO(gst_filename_to_uri, pFpp)
GO(gst_flagset_register, LFL)
//DATAB(_gst_flagset_type,
GO(gst_flow_get_name, pFi)
-GO(gst_flow_return_get_type, pFv)
+GO(gst_flow_return_get_type, LFv)
GO(gst_flow_to_quark, uFi)
GO(gst_format_get_by_nick, uFp)
GO(gst_format_get_details, pFu)
GO(gst_format_get_name, pFu)
-GO(gst_format_get_type, pFv)
+GO(gst_format_get_type, LFv)
GO(gst_format_iterate_definitions, pFv)
GO(gst_format_register, uFpp)
GO(gst_formats_contains, iFpu)
GO(gst_format_to_quark, uFu)
-GO(gst_fraction_get_type, pFv)
-GO(gst_fraction_range_get_type, pFv)
+GO(gst_fraction_get_type, LFv)
+GO(gst_fraction_range_get_type, LFv)
DATAB(_gst_fraction_range_type, sizeof(void*))
DATAB(_gst_fraction_type, sizeof(void*))
GO(gst_get_main_executable_path, pFv)
//GO(gst_ghost_pad_activate_mode_default,
//GO(gst_ghost_pad_construct,
//GO(gst_ghost_pad_get_target,
-//GO(gst_ghost_pad_get_type,
+GO(gst_ghost_pad_get_type, LFv)
//GO(gst_ghost_pad_internal_activate_mode_default,
-//GO(gst_ghost_pad_new,
+GO(gst_ghost_pad_new, pFpp)
//GO(gst_ghost_pad_new_from_template,
//GO(gst_ghost_pad_new_no_target,
//GO(gst_ghost_pad_new_no_target_from_template,
-//GO(gst_ghost_pad_set_target,
+GO(gst_ghost_pad_set_target, iFpp)
//GO(gst_g_thread_get_type,
//GO(gst_info_strdup_printf,
//GO(gst_info_strdup_vprintf,
-//GO(gst_info_vasprintf,
-GO(gst_init, vFpp)
-GO(gst_init_check, iFppp)
+GOM(gst_info_vasprintf, iFEppA)
+GOM(gst_init, vFEpp)
+GOM(gst_init_check, iFEppp)
GO(gst_init_get_option_group, pFv)
//GO(gst_int64_range_get_type,
//DATAB(_gst_int64_range_type,
-//GO(gst_int_range_get_type,
+GO(gst_int_range_get_type, LFv)
DATAB(_gst_int_range_type, sizeof(void*))
GO(gst_is_caps_features, iFp)
GO(gst_is_initialized, iFv)
//GO(gst_iterator_copy,
//GO(gst_iterator_filter,
//GO(gst_iterator_find_custom,
-//GO(gst_iterator_fold,
+GOM(gst_iterator_fold, iFEpppp)
//GO(gst_iterator_foreach,
GO(gst_iterator_free, vFp)
//GO(gst_iterator_get_type,
@@ -756,21 +757,21 @@ GO(gst_iterator_next, iFpp)
//GO(gst_iterator_result_get_type,
GO(gst_iterator_resync, vFp)
//GO(gst_library_error_get_type,
-//GO(gst_library_error_quark,
+GO(gst_library_error_quark, pFv)
//GO(gst_lock_flags_get_type,
-//GO(gst_make_element_message_details,
+GOM(gst_make_element_message_details, pFEpV)
//GO(gst_map_flags_get_type,
//DATA(gst_memory_alignment,
//GO(gst_memory_copy,
//GO(gst_memory_flags_get_type,
-//GO(gst_memory_get_sizes,
+GO(gst_memory_get_sizes, iFppp)
//GO(gst_memory_get_type,
GO(gst_memory_init, vFpuppLLLL)
//GO(gst_memory_is_span,
//GO(gst_memory_is_type,
//GO(gst_memory_make_mapped,
GO(gst_memory_map, iFppu)
-//GO(gst_memory_new_wrapped,
+GOM(gst_memory_new_wrapped, pFEipLLLpp)
//GO(gst_memory_ref,
//GO(gst_memory_resize,
//GO(gst_memory_share,
@@ -783,7 +784,7 @@ GO(gst_message_get_num_redirect_entries, lFp)
GO(gst_message_get_seqnum, uFp)
GO(gst_message_get_stream_status_object, pFp)
GO(gst_message_get_structure, pFp)
-GO(gst_message_get_type, pFv)
+GO(gst_message_get_type, LFv)
GO(gst_message_has_name, iFpp)
GO(gst_message_new_application, pFpp)
GO(gst_message_new_async_done, pFpU)
@@ -880,7 +881,7 @@ GO(gst_message_streams_selected_get_stream, pFpu)
GO(gst_message_take, iFpp)
DATAB(_gst_message_type, sizeof(void*))
GO(gst_message_type_get_name, pFi)
-GO(gst_message_type_get_type, pFv)
+GO(gst_message_type_get_type, LFv)
GO(gst_message_type_to_quark, uFi)
GO(gst_message_unref, vFp)
GO(gst_message_writable_structure, pFp)
@@ -904,7 +905,7 @@ GO(gst_mini_object_is_writable, iFp)
GO(gst_mini_object_make_writable, pFp)
GO(gst_mini_object_ref, pFp)
//GO(gst_mini_object_remove_parent,
-//GO(gst_mini_object_replace,
+GO(gst_mini_object_replace, iFpp)
GOM(gst_mini_object_set_qdata, vFEpppp)
//GO(gst_mini_object_steal,
//GO(gst_mini_object_steal_qdata,
@@ -917,14 +918,14 @@ GO(gst_object_add_control_binding, iFpp)
GO(gst_object_check_uniqueness, iFpp)
GO(gst_object_default_deep_notify, vFpppp)
GO(gst_object_default_error, vFppp)
-GO(gst_object_flags_get_type, pFv)
+GO(gst_object_flags_get_type, LFv)
GO(gst_object_get_control_binding, pFpp)
GO(gst_object_get_control_rate, LFp)
GO(gst_object_get_g_value_array, iFppLLup)
GO(gst_object_get_name, pFp)
GO(gst_object_get_parent, pFp)
GO(gst_object_get_path_string, pFp)
-GO(gst_object_get_type, pFv)
+GO(gst_object_get_type, LFv)
GO(gst_object_get_value, pFppL)
GO(gst_object_get_value_array, iFppLLup)
GO(gst_object_has_active_control_bindings, iFp)
@@ -945,17 +946,17 @@ GO(gst_object_sync_values, iFpL)
GO(gst_object_unparent, vFp)
GO(gst_object_unref, vFp)
GO(gst_pad_activate_mode, iFpii)
-//GO(gst_pad_add_probe, iFEpiBpB)
+GOM(gst_pad_add_probe, LFEpippp)
GO(gst_pad_can_link, iFpp)
GO(gst_pad_chain, iFpp)
GO(gst_pad_chain_list, iFpp)
GO(gst_pad_check_reconfigure, iFp)
GO(gst_pad_create_stream_id, pFppp)
-//GOM(gst_pad_create_stream_id_printf, pFEpppV)
-//GOM(gst_pad_create_stream_id_printf_valist, pFEpppA)
-GO(gst_pad_direction_get_type, pFv)
+GOM(gst_pad_create_stream_id_printf, pFEpppV)
+GOM(gst_pad_create_stream_id_printf_valist, pFEpppA)
+GO(gst_pad_direction_get_type, LFv)
GO(gst_pad_event_default, iFppp)
-GO(gst_pad_flags_get_type, pFv)
+GO(gst_pad_flags_get_type, LFv)
//GOM(gst_pad_forward, iFEpBp)
GO(gst_pad_get_allowed_caps, pFp)
GO(gst_pad_get_current_caps, pFp)
@@ -969,11 +970,11 @@ GO(gst_pad_get_parent_element, pFp)
GO(gst_pad_get_peer, pFp)
GO(gst_pad_get_range, iFpUup)
GO(gst_pad_get_single_internal_link, pFp)
-GO(gst_pad_get_sticky_event, pFppu)
+GO(gst_pad_get_sticky_event, pFpiu)
GO(gst_pad_get_stream, pFp)
GO(gst_pad_get_stream_id, pFp)
GO(gst_pad_get_task_state, iFp)
-GO(gst_pad_get_type, pFv)
+GO(gst_pad_get_type, LFv)
GO(gst_pad_has_current_caps, iFp)
GO(gst_pad_is_active, iFp)
GO(gst_pad_is_blocked, iFp)
@@ -982,15 +983,15 @@ GO(gst_pad_is_linked, iFp)
GO(gst_pad_iterate_internal_links, pFp)
GO(gst_pad_iterate_internal_links_default, pFpp)
GO(gst_pad_link, iFpp)
-GO(gst_pad_link_check_get_type, pFv)
+GO(gst_pad_link_check_get_type, LFv)
GO(gst_pad_link_full, iFppi)
GO(gst_pad_link_get_name, pFi)
GO(gst_pad_link_maybe_ghosting, iFpp)
GO(gst_pad_link_maybe_ghosting_full, iFppi)
-GO(gst_pad_link_return_get_type, pFv)
+GO(gst_pad_link_return_get_type, LFv)
GO(gst_pad_mark_reconfigure, vFp)
GO(gst_pad_mode_get_name, pFu)
-GO(gst_pad_mode_get_type, pFv)
+GO(gst_pad_mode_get_type, LFv)
GO(gst_pad_needs_reconfigure, iFp)
GO(gst_pad_new, pFpi)
GO(gst_pad_new_from_static_template, pFpp)
@@ -1002,7 +1003,7 @@ GO(gst_pad_peer_query_caps, pFpp)
GO(gst_pad_peer_query_convert, iFpiIip)
GO(gst_pad_peer_query_duration, iFpip)
GO(gst_pad_peer_query_position, iFpip)
-GO(gst_pad_presence_get_type, pFv)
+GO(gst_pad_presence_get_type, LFv)
//GO(gst_pad_probe_info_get_buffer,
GO(gst_pad_probe_info_get_buffer_list, pFp)
//GO(gst_pad_probe_info_get_event,
@@ -1024,7 +1025,7 @@ GO(gst_pad_query_duration, iFppp)
GO(gst_pad_query_position, iFppp)
GO(gst_pad_remove_probe, vFpL)
GO(gst_pad_send_event, iFpp)
-//GOM(gst_pad_set_activate_function_full, vFEpBpB)
+GOM(gst_pad_set_activate_function_full, vFEpppp)
GOM(gst_pad_set_activatemode_function_full, vFEpppp)
GO(gst_pad_set_active, iFpi)
GOM(gst_pad_set_chain_function_full, vFEpppp)
@@ -1034,21 +1035,21 @@ GO(gst_pad_set_element_private, vFpp)
GOM(gst_pad_set_event_function_full, vFEpppp)
GOM(gst_pad_set_getrange_function_full, vFEpppp)
//GOM(gst_pad_set_iterate_internal_links_function_full, vFEpBpB)
-//GOM(gst_pad_set_link_function_full, vFEpBpB)
+GOM(gst_pad_set_link_function_full, vFEpppp)
GO(gst_pad_set_offset, vFpI)
GOM(gst_pad_set_query_function_full, vFEpppp)
//GOM(gst_pad_set_unlink_function_full, vFEpBpB)
-//GOM(gst_pad_start_task, vFEpBpB)
+GOM(gst_pad_start_task, iFEpppp)
//GOM(gst_pad_sticky_events_foreach, vFEpBp)
GO(gst_pad_stop_task, iFp)
GO(gst_pad_store_sticky_event, iFpp)
-GO(gst_pad_template_flags_get_type, pFv)
-//GO(gst_pad_template_get_caps,
+GO(gst_pad_template_flags_get_type, LFv)
+GO(gst_pad_template_get_caps, pFp)
//GO(gst_pad_template_get_documentation_caps,
//GO(gst_pad_template_get_type,
GO(gst_pad_template_new, pFpiip)
//GO(gst_pad_template_new_from_static_pad_template_with_gtype,
-//GO(gst_pad_template_new_with_gtype,
+GO(gst_pad_template_new_with_gtype, pFpiipL)
//GO(gst_pad_template_pad_created,
//GO(gst_pad_template_set_documentation_caps,
GO(gst_pad_unlink, iFpp)
@@ -1122,8 +1123,8 @@ GO(gst_plugin_is_loaded, iFp)
GO(gst_plugin_load, pFp)
GO(gst_plugin_load_by_name, pFp)
//GO(_gst_plugin_loader_client_run,
-GO(gst_plugin_load_file, pFpp)
-//GO(gst_plugin_register_static,
+GOM(gst_plugin_load_file, pFEpp)
+GOM(gst_plugin_register_static, iFEiipppppppp)
//GO(gst_plugin_register_static_full,
GO(gst_plugin_set_cache_data, vFpp)
//GO(gst_poll_add_fd,
@@ -1153,7 +1154,7 @@ GO(gst_preset_delete_preset, iFpp)
GO(gst_preset_get_meta, iFpppp)
//GO(gst_preset_get_preset_names,
GO(gst_preset_get_property_names, pFp)
-//GO(gst_preset_get_type,
+GO(gst_preset_get_type, LFv)
GO(gst_preset_is_editable, iFp)
//GO(gst_preset_load_preset,
GO(gst_preset_rename_preset, iFppp)
@@ -1200,7 +1201,7 @@ GO(gst_query_get_n_allocation_pools, uFp)
GO(gst_query_get_n_buffering_ranges, uFp)
GO(gst_query_get_n_scheduling_modes, uFp)
GO(gst_query_get_structure, pFp)
-GO(gst_query_get_type, pFv)
+GO(gst_query_get_type, LFv)
GO(gst_query_has_scheduling_mode, iFpi)
GO(gst_query_has_scheduling_mode_with_flags, iFpii)
GO(gst_query_new_accept_caps, pFp)
@@ -1276,10 +1277,10 @@ GO(gst_query_set_uri_redirection, vFpp)
GO(gst_query_set_uri_redirection_permanent, vFpi)
GO(gst_query_take, iFpp)
//DATAB(_gst_query_type,
-GO(gst_query_type_flags_get_type, pFv)
+GO(gst_query_type_flags_get_type, LFv)
GO(gst_query_type_get_flags, uFu)
GO(gst_query_type_get_name, pFu)
-GO(gst_query_type_get_type, pFv)
+GO(gst_query_type_get_type, LFv)
GO(gst_query_type_to_quark, uFu)
GO(gst_query_unref, vFp)
GO(gst_query_writable_structure, pFp)
@@ -1307,14 +1308,14 @@ GO(gst_registry_remove_feature, vFpp)
GO(gst_registry_remove_plugin, vFpp)
GO(gst_registry_scan_path, iFpp)
//GO(gst_resource_error_get_type,
-//GO(gst_resource_error_quark,
+GO(gst_resource_error_quark, pFv)
GO(gst_sample_copy, pFp)
GO(gst_sample_get_buffer, pFp)
GO(gst_sample_get_buffer_list, pFp)
GO(gst_sample_get_caps, pFp)
GO(gst_sample_get_info, pFp)
GO(gst_sample_get_segment, pFp)
-GO(gst_sample_get_type, pFv)
+GO(gst_sample_get_type, LFv)
GO(gst_sample_new, pFpppp)
GO(gst_sample_ref, pFp)
//GO(gst_sample_set_buffer,
@@ -1324,17 +1325,17 @@ GO(gst_sample_set_info, iFpp)
GO(gst_sample_set_segment, vFpp)
DATAB(_gst_sample_type, sizeof(long))
//GO(gst_sample_unref,
-GO(gst_scheduling_flags_get_type, pFv)
-GO(gst_search_mode_get_type, pFv)
-GO(gst_seek_flags_get_type, pFv)
-GO(gst_seek_type_get_type, pFv)
+GO(gst_scheduling_flags_get_type, LFv)
+GO(gst_search_mode_get_type, LFv)
+GO(gst_seek_flags_get_type, LFv)
+GO(gst_seek_type_get_type, LFv)
GO(gst_segment_clip, iFpuLLpp)
GO(gst_segment_copy, pFp)
GO(gst_segment_copy_into, vFpp)
GO(gst_segment_do_seek, iFpduuuLuLp)
-GO(gst_segment_flags_get_type, pFv)
+GO(gst_segment_flags_get_type, LFv)
GO(gst_segment_free, vFp)
-GO(gst_segment_get_type, pFv)
+GO(gst_segment_get_type, LFv)
GO(gst_segment_init, vFpu)
GO(gst_segment_is_equal, iFpp)
GO(gst_segment_new, pFv)
@@ -1351,17 +1352,17 @@ GO(gst_segment_to_stream_time, UFpiU)
GO(gst_segment_to_stream_time_full, iFpiUp)
GO(gst_segtrap_is_enabled, iFv)
GO(gst_segtrap_set_enabled, vFi)
-GO(gst_stack_trace_flags_get_type, pFv)
+GO(gst_stack_trace_flags_get_type, LFv)
GO(gst_state_change_get_name, pFu)
-GO(gst_state_change_get_type, pFv)
-GO(gst_state_change_return_get_type, pFv)
-GO(gst_state_get_type, pFv)
+GO(gst_state_change_get_type, LFv)
+GO(gst_state_change_return_get_type, LFv)
+GO(gst_state_get_type, LFv)
GO(gst_static_caps_cleanup, vFp)
GO(gst_static_caps_get, pFp)
-GO(gst_static_caps_get_type, pFv)
-//GO(gst_static_pad_template_get,
-//GO(gst_static_pad_template_get_caps,
-//GO(gst_static_pad_template_get_type,
+GO(gst_static_caps_get_type, LFv)
+GO(gst_static_pad_template_get, pFp)
+GO(gst_static_pad_template_get_caps, pFp)
+GO(gst_static_pad_template_get_type, LFv)
GO(gst_stream_collection_add_stream, iFpp)
GO(gst_stream_collection_get_size, uFp)
GO(gst_stream_collection_get_stream, pFpu)
@@ -1369,7 +1370,7 @@ GO(gst_stream_collection_get_stream, pFpu)
GO(gst_stream_collection_get_upstream_id, pFp)
GO(gst_stream_collection_new, pFp)
//GO(gst_stream_error_get_type,
-//GO(gst_stream_error_quark,
+GO(gst_stream_error_quark, pFv)
//GO(gst_stream_flags_get_type,
GO(gst_stream_get_caps, pFp)
GO(gst_stream_get_stream_flags, uFp)
@@ -1388,7 +1389,7 @@ GO(gst_stream_type_get_name, pFu)
GO(gst_structure_can_intersect, iFpp)
//GO(gst_structure_change_type_get_type,
GO(gst_structure_copy, pFp)
-//GOM(gst_structure_filter_and_map_in_place, vFEpBp)
+GOM(gst_structure_filter_and_map_in_place, vFEppp)
GO(gst_structure_fixate, vFp)
GO(gst_structure_fixate_field, iFpp)
GO(gst_structure_fixate_field_boolean, iFppi)
@@ -1396,7 +1397,7 @@ GO(gst_structure_fixate_field_nearest_double, iFppd)
GO(gst_structure_fixate_field_nearest_fraction, iFppii)
GO(gst_structure_fixate_field_nearest_int, iFppi)
GO(gst_structure_fixate_field_string, iFppp)
-//GOM(gst_structure_foreach, iFEpBp)
+GOM(gst_structure_foreach, iFEppp)
GO(gst_structure_free, vFp)
GO(gst_structure_from_string, pFpp)
GOM(gst_structure_get, iFEppV)
@@ -1416,7 +1417,7 @@ GO(gst_structure_get_list, iFppp)
GO(gst_structure_get_name, pFp)
GO(gst_structure_get_name_id, uFp)
GO(gst_structure_get_string, pFpp)
-GO(gst_structure_get_type, pFv)
+GO(gst_structure_get_type, LFv)
GO(gst_structure_get_uint, iFppp)
GO(gst_structure_get_uint64, iFppp)
GOM(gst_structure_get_valist, iFEppA)
@@ -1442,19 +1443,19 @@ GO(gst_structure_new_empty, pFp)
GO(gst_structure_new_from_string, pFp)
//GOM(gst_structure_new_id, pFEppV)
GO(gst_structure_new_id_empty, pFu)
-//GOM(gst_structure_new_valist, pFppA)
+GOM(gst_structure_new_valist, pFppA)
GO(gst_structure_n_fields, iFp)
GO(gst_structure_nth_field_name, pFpu)
GO(gst_structure_remove_all_fields, vFp)
GO(gst_structure_remove_field, vFpp)
GOM(gst_structure_remove_fields, vFEppV)
GOM(gst_structure_remove_fields_valist, vFEppA)
-//GOM(gst_structure_set, vFEppV)
+GOM(gst_structure_set, vFEppV)
GO(gst_structure_set_array, vFppp)
GO(gst_structure_set_list, vFppp)
GO(gst_structure_set_name, vFpp)
GO(gst_structure_set_parent_refcount, iFpp)
-//GOM(gst_structure_set_valist, vFEppA)
+GOM(gst_structure_set_valist, vFEppA)
GO(gst_structure_set_value, vFppp)
GO(gst_structure_take, iFpp)
GO(gst_structure_take_value, vFppp)
@@ -1468,16 +1469,16 @@ GO(gst_system_clock_set_default, vFp)
GO(gst_tag_get_description, pFp)
GO(gst_tag_get_flag, uFp)
//GO(gst_tag_get_nick,
-//GO(gst_tag_get_type,
+GO(gst_tag_get_type, LFp)
//GO(gst_tag_is_fixed,
-//GOM(gst_tag_list_add, vFEpipV)
-//GOM(gst_tag_list_add_valist, vFEpipA)
-//GOM(gst_tag_list_add_valist_values, vFEpipA)
+GOM(gst_tag_list_add, vFEpipV)
+GOM(gst_tag_list_add_valist, vFEpipA)
+GOM(gst_tag_list_add_valist_values, vFEpipA)
GO(gst_tag_list_add_value, vFpipp)
-//GOM(gst_tag_list_add_values, vFEpipV)
+GOM(gst_tag_list_add_values, vFEpipV)
GO(gst_tag_list_copy, pFp)
GO(gst_tag_list_copy_value, iFppp)
-//GOM(gst_tag_list_foreach, vFEpBp)
+GOM(gst_tag_list_foreach, vFEppp)
GO(gst_tag_list_get_boolean, iFppp)
GO(gst_tag_list_get_boolean_index, iFppup)
GO(gst_tag_list_get_date, iFppp)
@@ -1500,7 +1501,7 @@ GO(gst_tag_list_get_scope, iFp)
GO(gst_tag_list_get_string, iFppp)
GO(gst_tag_list_get_string_index, iFppup)
GO(gst_tag_list_get_tag_size, uFpp)
-GO(gst_tag_list_get_type, pFv)
+GO(gst_tag_list_get_type, LFv)
GO(gst_tag_list_get_uint, iFppp)
GO(gst_tag_list_get_uint64, iFppp)
GO(gst_tag_list_get_uint64_index, iFppup)
@@ -1510,10 +1511,10 @@ GO(gst_tag_list_insert, vFppi)
GO(gst_tag_list_is_empty, iFp)
GO(gst_tag_list_is_equal, iFpp)
GO(gst_tag_list_merge, pFppi)
-//GOM(gst_tag_list_new, pFEpV)
+GOM(gst_tag_list_new, pFEpV)
GO(gst_tag_list_new_empty, pFv)
GO(gst_tag_list_new_from_string, pFp)
-//GOM(gst_tag_list_new_valist, pFA)
+GOM(gst_tag_list_new_valist, pFA)
GO(gst_tag_list_n_tags, iFp)
GO(gst_tag_list_nth_tag_name, pFpu)
GO(gst_tag_list_peek_string_index, iFppup)
@@ -1525,7 +1526,7 @@ GO(gst_tag_list_take, iFpp)
GO(gst_tag_list_to_string, pFp)
DATAB(_gst_tag_list_type, sizeof(void*))
GO(gst_tag_list_unref, vFp)
-GO(gst_tag_merge_mode_get_type, pFv)
+GO(gst_tag_merge_mode_get_type, LFv)
//GO(gst_tag_merge_strings_with_comma,
//GO(gst_tag_merge_use_first,
//GO(gst_tag_register,
@@ -1536,21 +1537,21 @@ GO(gst_tag_merge_mode_get_type, pFv)
//GO(gst_tag_setter_add_tag_valist_values,
GO(gst_tag_setter_add_tag_value, vFpupp)
//GO(gst_tag_setter_add_tag_values,
-//GO(gst_tag_setter_get_tag_list,
+GO(gst_tag_setter_get_tag_list, pFp)
GO(gst_tag_setter_get_tag_merge_mode, uFp)
-//GO(gst_tag_setter_get_type,
-//GO(gst_tag_setter_merge_tags,
+GO(gst_tag_setter_get_type, LFv)
+GO(gst_tag_setter_merge_tags, vFppi)
GO(gst_tag_setter_reset_tags, vFp)
GO(gst_tag_setter_set_tag_merge_mode, vFpu)
//GO(gst_task_cleanup_all,
//GO(gst_task_get_pool,
//GO(gst_task_get_state,
-GO(gst_task_get_type, pFv)
-//GO(gst_task_join,
-//GO(gst_task_new,
-//GO(gst_task_pause,
+GO(gst_task_get_type, LFv)
+GO(gst_task_join, iFp)
+GOM(gst_task_new, pFEppp)
+GO(gst_task_pause, iFp)
GO(gst_task_pool_cleanup, vFp)
-GO(gst_task_pool_get_type, pFv)
+GO(gst_task_pool_get_type, LFv)
//GO(gst_task_pool_join,
//GO(gst_task_pool_new,
GO(gst_task_pool_prepare, vFp)
@@ -1558,12 +1559,12 @@ GO(gst_task_pool_prepare, vFp)
//GO(gst_task_resume,
//GO(gst_task_set_enter_callback,
//GO(gst_task_set_leave_callback,
-//GO(gst_task_set_lock,
+GO(gst_task_set_lock, vFpp)
GO(gst_task_set_pool, vFpp)
//GO(gst_task_set_state,
-//GO(gst_task_start,
-//GO(gst_task_state_get_type,
-//GO(gst_task_stop,
+GO(gst_task_start, iFp)
+GO(gst_task_state_get_type, LFv)
+GO(gst_task_stop, iFp)
GO(gst_toc_append_entry, vFpp)
//GO(gst_toc_dump,
GO(gst_toc_entry_append_sub_entry, vFpp)
@@ -1572,24 +1573,24 @@ GO(gst_toc_entry_get_loop, iFppp)
GO(gst_toc_entry_get_parent, pFp)
GO(gst_toc_entry_get_start_stop_times, iFppp)
GO(gst_toc_entry_get_sub_entries, pFp)
-//GO(gst_toc_entry_get_tags,
+GO(gst_toc_entry_get_tags, pFp)
GO(gst_toc_entry_get_toc, pFp)
//GO(gst_toc_entry_get_type,
GO(gst_toc_entry_get_uid, pFp)
//GO(gst_toc_entry_is_alternative,
GO(gst_toc_entry_is_sequence, iFp)
-//GO(gst_toc_entry_merge_tags,
+GO(gst_toc_entry_merge_tags, vFppi)
GO(gst_toc_entry_new, pFip)
GO(gst_toc_entry_set_loop, vFpui)
GO(gst_toc_entry_set_start_stop_times, vFpll)
-//GO(gst_toc_entry_set_tags,
+GO(gst_toc_entry_set_tags, vFpp)
//DATAB(_gst_toc_entry_type,
GO(gst_toc_entry_type_get_nick, pFi)
//GO(gst_toc_entry_type_get_type,
GO(gst_toc_find_entry, pFpp)
GO(gst_toc_get_entries, pFp)
GO(gst_toc_get_scope, uFp)
-//GO(gst_toc_get_tags,
+GO(gst_toc_get_tags, pFp)
//GO(gst_toc_get_type,
//GO(gst_toc_loop_type_get_type,
//GO(gst_toc_merge_tags,
@@ -1597,7 +1598,7 @@ GO(gst_toc_new, pFu)
//GO(gst_toc_scope_get_type,
//GO(gst_toc_set_tags,
GO(gst_toc_setter_get_toc, pFp)
-//GO(gst_toc_setter_get_type,
+GO(gst_toc_setter_get_type, LFv)
GO(gst_toc_setter_reset, vFp)
GO(gst_toc_setter_set_toc, vFpp)
DATAB(_gst_toc_type, sizeof(void*))
@@ -1619,12 +1620,12 @@ GO(gst_type_find_factory_get_extensions, pFp)
GO(gst_type_find_factory_get_list, pFv)
//GO(gst_type_find_factory_get_type,
GO(gst_type_find_factory_has_function, iFp)
-//GO(gst_type_find_get_length,
+GO(gst_type_find_get_length, UFp)
//GO(gst_type_find_get_type,
-//GO(gst_type_find_peek,
+GO(gst_type_find_peek, pFpUu)
//GO(gst_type_find_probability_get_type,
-//GO(gst_type_find_register,
-//GO(gst_type_find_suggest,
+GOM(gst_type_find_register, iFEppuppppp)
+GO(gst_type_find_suggest, vFpup)
//GO(gst_type_find_suggest_simple,
GO(gst_type_is_plugin_api, iFLp)
GO(gst_type_mark_as_plugin_api, vFLu)
@@ -1635,7 +1636,7 @@ GO(gst_update_registry, iFv)
GO(gst_uri_copy, pFp)
GO(gst_uri_equal, iFpp)
//GO(gst_uri_error_get_type,
-//GO(gst_uri_error_quark,
+GO(gst_uri_error_quark, pFv)
//GO(gst_uri_from_string,
GO(gst_uri_from_string_escaped, pFp)
GO(gst_uri_from_string_with_base, pFpp)
@@ -1656,13 +1657,13 @@ GO(gst_uri_get_query_value, pFpp)
//GO(gst_uri_get_type,
//GO(gst_uri_get_userinfo,
GO(gst_uri_handler_get_protocols, pFp)
-//GO(gst_uri_handler_get_type,
+GO(gst_uri_handler_get_type, LFv)
GO(gst_uri_handler_get_uri, pFp)
GO(gst_uri_handler_get_uri_type, uFp)
GO(gst_uri_handler_set_uri, iFppp)
GO(gst_uri_has_protocol, iFpp)
GO(gst_uri_is_normalized, iFp)
-//GO(gst_uri_is_valid,
+GO(gst_uri_is_valid, iFp)
//GO(gst_uri_is_writable,
GO(gst_uri_join, pFpp)
GO(gst_uri_join_strings, pFpp)
@@ -1689,13 +1690,13 @@ GO(gst_uri_set_query_value, iFppp)
//GO(gst_uri_to_string,
//GO(gst_uri_type_get_type,
//GO(gst_uri_unref,
-//GO(gst_util_array_binary_search,
+GOM(gst_util_array_binary_search, pFpuLpipp)
GO(gst_util_double_to_fraction, vFdpp)
//GO(gst_util_dump_buffer,
GO(gst_util_dump_mem, vFpu)
GO(gst_util_fraction_add, iFiiiipp)
GO(gst_util_fraction_compare, iFiiii)
-//GO(gst_util_fraction_multiply,
+GO(gst_util_fraction_multiply, iFiiiipp)
GO(gst_util_fraction_to_double, vFiip)
GO(gst_util_gdouble_to_guint64, LFd)
GO(gst_util_get_object_array, iFppp)
@@ -1711,13 +1712,13 @@ GO(gst_util_set_object_array, iFppp)
GO(gst_util_set_value_from_string, vFpp)
GO(gst_util_uint64_scale, UFUUU)
GO(gst_util_uint64_scale_ceil, LFLLL)
-//GO(gst_util_uint64_scale_int,
+GO(gst_util_uint64_scale_int, UFUii)
GO(gst_util_uint64_scale_int_ceil, LFLii)
-//GO(gst_util_uint64_scale_int_round,
-//GO(gst_util_uint64_scale_round,
+GO(gst_util_uint64_scale_int_round, UFUii)
+GO(gst_util_uint64_scale_round, UFUUU)
GO(gst_value_array_append_and_take_value, vFpp)
-//GO(gst_value_array_append_value,
-//GO(gst_value_array_get_size,
+GO(gst_value_array_append_value, vFpp)
+GO(gst_value_array_get_size, iFp)
//GO(gst_value_array_get_type,
GO(gst_value_array_get_value, pFpu)
GO(gst_value_array_init, pFpu)
@@ -1733,41 +1734,41 @@ GO(gst_value_fixate, iFpp)
//GO(gst_value_fraction_multiply,
//GO(gst_value_fraction_subtract,
GO(gst_value_get_bitmask, LFp)
-//GO(gst_value_get_caps,
+GO(gst_value_get_caps, pFp)
GO(gst_value_get_caps_features, pFp)
GO(gst_value_get_double_range_max, dFp)
//GO(gst_value_get_double_range_min,
-//GO(gst_value_get_flagset_flags,
+GO(gst_value_get_flagset_flags, uFp)
GO(gst_value_get_flagset_mask, uFp)
GO(gst_value_get_fraction_denominator, iFp)
-//GO(gst_value_get_fraction_numerator,
+GO(gst_value_get_fraction_numerator, iFp)
GO(gst_value_get_fraction_range_max, pFp)
-//GO(gst_value_get_fraction_range_min,
+GO(gst_value_get_fraction_range_min, pFp)
//GO(gst_value_get_int64_range_max,
//GO(gst_value_get_int64_range_min,
GO(gst_value_get_int64_range_step, lFp)
-//GO(gst_value_get_int_range_max,
-//GO(gst_value_get_int_range_min,
+GO(gst_value_get_int_range_max, iFp)
+GO(gst_value_get_int_range_min, iFp)
//GO(gst_value_get_int_range_step,
GO(gst_value_get_structure, pFp)
-//GO(gst_value_init_and_copy,
+GO(gst_value_init_and_copy, vFpp)
//GO(gst_value_intersect,
GO(gst_value_is_fixed, iFp)
//GO(gst_value_is_subset,
-//GO(gst_value_list_append_and_take_value,
-//GO(gst_value_list_append_value,
+GO(gst_value_list_append_and_take_value, vFpp)
+GO(gst_value_list_append_value, vFpp)
//GO(gst_value_list_concat,
-//GO(gst_value_list_get_size,
-//GO(gst_value_list_get_type,
-//GO(gst_value_list_get_value,
+GO(gst_value_list_get_size, uFp)
+GO(gst_value_list_get_type, LFv)
+GO(gst_value_list_get_value, pFpu)
//GO(gst_value_list_init,
-//GO(gst_value_list_merge,
+GO(gst_value_list_merge, vFppp)
//GO(gst_value_list_prepend_value,
DATAB(_gst_value_list_type, sizeof(void*))
//GO(gst_value_register,
GO(gst_value_serialize, pFp)
GO(gst_value_set_bitmask, vFpL)
-//GO(gst_value_set_caps,
+GO(gst_value_set_caps, vFpp)
GO(gst_value_set_caps_features, vFpp)
GO(gst_value_set_double_range, vFpdd)
GO(gst_value_set_flagset, vFpuu)
@@ -1776,10 +1777,12 @@ GO(gst_value_set_fraction_range, vFppp)
GO(gst_value_set_fraction_range_full, vFpiiii)
GO(gst_value_set_int64_range, vFpll)
GO(gst_value_set_int64_range_step, vFplll)
-//GO(gst_value_set_int_range,
+GO(gst_value_set_int_range, vFpii)
GO(gst_value_set_int_range_step, vFpiii)
GO(gst_value_set_structure, vFpp)
GO(gst_value_subtract, iFppp)
//GO(gst_value_union,
GO(gst_version, vFpppp)
GO(gst_version_string, pFv)
+
+GO(dummy_iFpipLpp, iFpipLpp) // for gtkclass \ No newline at end of file
diff --git a/src/wrapped/wrappedgstriff.c b/src/wrapped/wrappedgstriff.c
new file mode 100644
index 0000000..35a300f
--- /dev/null
+++ b/src/wrapped/wrappedgstriff.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* gstriffName = "libgstriff-1.0.so.0";
+#define LIBNAME gstriff
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstriff_private.h b/src/wrapped/wrappedgstriff_private.h
new file mode 100644
index 0000000..1952be9
--- /dev/null
+++ b/src/wrapped/wrappedgstriff_private.h
@@ -0,0 +1,19 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(gst_riff_create_audio_caps, pFWpppppp)
+GO(gst_riff_create_audio_template_caps, pFv)
+//GO(gst_riff_create_iavs_caps,
+//GO(gst_riff_create_iavs_template_caps,
+GO(gst_riff_create_video_caps, pFuppppp)
+GO(gst_riff_create_video_template_caps, pFv)
+GO(gst_riff_init, vFv)
+//GO(gst_riff_parse_chunk,
+//GO(gst_riff_parse_file_header,
+//GO(gst_riff_parse_info,
+//GO(gst_riff_parse_strf_auds,
+//GO(gst_riff_parse_strf_iavs,
+//GO(gst_riff_parse_strf_vids,
+//GO(gst_riff_parse_strh,
+//GO(gst_riff_read_chunk,
diff --git a/src/wrapped/wrappedgstrtp.c b/src/wrapped/wrappedgstrtp.c
new file mode 100644
index 0000000..ef3fa6a
--- /dev/null
+++ b/src/wrapped/wrappedgstrtp.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstrtpName = "libgstrtp-1.0.so";
+#else
+ const char* gstrtpName = "libgstrtp-1.0.so.0";
+#endif
+
+#define LIBNAME gstrtp
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstrtp_private.h b/src/wrapped/wrappedgstrtp_private.h
new file mode 100644
index 0000000..91c55cb
--- /dev/null
+++ b/src/wrapped/wrappedgstrtp_private.h
@@ -0,0 +1,215 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+//GO(gst_buffer_add_rtp_source_meta,
+//GO(gst_buffer_get_rtp_source_meta,
+//GO(gst_rtcp_buffer_add_packet,
+//GO(gst_rtcp_buffer_get_first_packet,
+//GO(gst_rtcp_buffer_get_packet_count,
+//GO(gst_rtcp_buffer_map,
+//GO(gst_rtcp_buffer_new,
+//GO(gst_rtcp_buffer_new_copy_data,
+//GO(gst_rtcp_buffer_new_take_data,
+//GO(gst_rtcp_buffer_unmap,
+//GO(gst_rtcp_buffer_validate,
+//GO(gst_rtcp_buffer_validate_data,
+//GO(gst_rtcp_buffer_validate_data_reduced,
+//GO(gst_rtcp_buffer_validate_reduced,
+GO(gst_rtcpfb_type_get_type, LFv)
+//GO(gst_rtcp_ntp_to_unix,
+//GO(gst_rtcp_packet_add_profile_specific_ext,
+//GO(gst_rtcp_packet_add_rb,
+//GO(gst_rtcp_packet_app_get_data,
+//GO(gst_rtcp_packet_app_get_data_length,
+//GO(gst_rtcp_packet_app_get_name,
+//GO(gst_rtcp_packet_app_get_ssrc,
+//GO(gst_rtcp_packet_app_get_subtype,
+//GO(gst_rtcp_packet_app_set_data_length,
+//GO(gst_rtcp_packet_app_set_name,
+//GO(gst_rtcp_packet_app_set_ssrc,
+//GO(gst_rtcp_packet_app_set_subtype,
+//GO(gst_rtcp_packet_bye_add_ssrc,
+//GO(gst_rtcp_packet_bye_add_ssrcs,
+//GO(gst_rtcp_packet_bye_get_nth_ssrc,
+//GO(gst_rtcp_packet_bye_get_reason,
+//GO(gst_rtcp_packet_bye_get_reason_len,
+//GO(gst_rtcp_packet_bye_get_ssrc_count,
+//GO(gst_rtcp_packet_bye_set_reason,
+//GO(gst_rtcp_packet_copy_profile_specific_ext,
+//GO(gst_rtcp_packet_fb_get_fci,
+//GO(gst_rtcp_packet_fb_get_fci_length,
+//GO(gst_rtcp_packet_fb_get_media_ssrc,
+//GO(gst_rtcp_packet_fb_get_sender_ssrc,
+GO(gst_rtcp_packet_fb_get_type, LFv)
+//GO(gst_rtcp_packet_fb_set_fci_length,
+//GO(gst_rtcp_packet_fb_set_media_ssrc,
+//GO(gst_rtcp_packet_fb_set_sender_ssrc,
+//GO(gst_rtcp_packet_fb_set_type,
+//GO(gst_rtcp_packet_get_count,
+//GO(gst_rtcp_packet_get_length,
+//GO(gst_rtcp_packet_get_padding,
+//GO(gst_rtcp_packet_get_profile_specific_ext,
+//GO(gst_rtcp_packet_get_profile_specific_ext_length,
+//GO(gst_rtcp_packet_get_rb,
+//GO(gst_rtcp_packet_get_rb_count,
+GO(gst_rtcp_packet_get_type, LFv)
+//GO(gst_rtcp_packet_move_to_next,
+//GO(gst_rtcp_packet_remove,
+//GO(gst_rtcp_packet_rr_get_ssrc,
+//GO(gst_rtcp_packet_rr_set_ssrc,
+//GO(gst_rtcp_packet_sdes_add_entry,
+//GO(gst_rtcp_packet_sdes_add_item,
+//GO(gst_rtcp_packet_sdes_copy_entry,
+//GO(gst_rtcp_packet_sdes_first_entry,
+//GO(gst_rtcp_packet_sdes_first_item,
+//GO(gst_rtcp_packet_sdes_get_entry,
+//GO(gst_rtcp_packet_sdes_get_item_count,
+//GO(gst_rtcp_packet_sdes_get_ssrc,
+//GO(gst_rtcp_packet_sdes_next_entry,
+//GO(gst_rtcp_packet_sdes_next_item,
+//GO(gst_rtcp_packet_set_rb,
+//GO(gst_rtcp_packet_sr_get_sender_info,
+//GO(gst_rtcp_packet_sr_set_sender_info,
+//GO(gst_rtcp_packet_xr_first_rb,
+//GO(gst_rtcp_packet_xr_get_block_length,
+//GO(gst_rtcp_packet_xr_get_block_type,
+//GO(gst_rtcp_packet_xr_get_dlrr_block,
+//GO(gst_rtcp_packet_xr_get_prt_by_seq,
+//GO(gst_rtcp_packet_xr_get_prt_info,
+//GO(gst_rtcp_packet_xr_get_rle_info,
+//GO(gst_rtcp_packet_xr_get_rle_nth_chunk,
+//GO(gst_rtcp_packet_xr_get_rrt,
+//GO(gst_rtcp_packet_xr_get_ssrc,
+//GO(gst_rtcp_packet_xr_get_summary_info,
+//GO(gst_rtcp_packet_xr_get_summary_jitter,
+//GO(gst_rtcp_packet_xr_get_summary_pkt,
+//GO(gst_rtcp_packet_xr_get_summary_ttl,
+//GO(gst_rtcp_packet_xr_get_voip_burst_metrics,
+//GO(gst_rtcp_packet_xr_get_voip_configuration_params,
+//GO(gst_rtcp_packet_xr_get_voip_delay_metrics,
+//GO(gst_rtcp_packet_xr_get_voip_jitter_buffer_params,
+//GO(gst_rtcp_packet_xr_get_voip_metrics_ssrc,
+//GO(gst_rtcp_packet_xr_get_voip_packet_metrics,
+//GO(gst_rtcp_packet_xr_get_voip_quality_metrics,
+//GO(gst_rtcp_packet_xr_get_voip_signal_metrics,
+//GO(gst_rtcp_packet_xr_next_rb,
+//GO(gst_rtcp_sdes_name_to_type,
+GO(gst_rtcpsdes_type_get_type, LFv)
+//GO(gst_rtcp_sdes_type_to_name,
+GO(gst_rtcp_type_get_type, LFv)
+//GO(gst_rtcp_unix_to_ntp,
+GO(gst_rtcpxr_type_get_type, LFv)
+//GO(gst_rtp_base_audio_payload_flush,
+//GO(gst_rtp_base_audio_payload_get_adapter,
+GO(gst_rtp_base_audio_payload_get_type, LFv)
+//GO(gst_rtp_base_audio_payload_push,
+//GO(gst_rtp_base_audio_payload_set_frame_based,
+//GO(gst_rtp_base_audio_payload_set_frame_options,
+//GO(gst_rtp_base_audio_payload_set_sample_based,
+//GO(gst_rtp_base_audio_payload_set_samplebits_options,
+//GO(gst_rtp_base_audio_payload_set_sample_options,
+GO(gst_rtp_base_depayload_get_type, LFv)
+//GO(gst_rtp_base_depayload_is_source_info_enabled,
+//GO(gst_rtp_base_depayload_push,
+//GO(gst_rtp_base_depayload_push_list,
+//GO(gst_rtp_base_depayload_set_source_info_enabled,
+//GO(gst_rtp_base_payload_allocate_output_buffer,
+//GO(gst_rtp_base_payload_get_source_count,
+GO(gst_rtp_base_payload_get_type, LFv)
+//GO(gst_rtp_base_payload_is_filled,
+//GO(gst_rtp_base_payload_is_source_info_enabled,
+//GO(gst_rtp_base_payload_push,
+//GO(gst_rtp_base_payload_push_list,
+//GO(gst_rtp_base_payload_set_options,
+//GO(gst_rtp_base_payload_set_outcaps,
+//GO(gst_rtp_base_payload_set_outcaps_structure,
+//GO(gst_rtp_base_payload_set_source_info_enabled,
+//GO(gst_rtp_buffer_add_extension_onebyte_header,
+//GO(gst_rtp_buffer_add_extension_twobytes_header,
+//GO(gst_rtp_buffer_allocate_data,
+//GO(gst_rtp_buffer_calc_header_len,
+//GO(gst_rtp_buffer_calc_packet_len,
+//GO(gst_rtp_buffer_calc_payload_len,
+//GO(gst_rtp_buffer_compare_seqnum,
+//GO(gst_rtp_buffer_default_clock_rate,
+//GO(gst_rtp_buffer_ext_timestamp,
+GO(gst_rtp_buffer_flags_get_type, LFv)
+//GO(gst_rtp_buffer_get_csrc,
+//GO(gst_rtp_buffer_get_csrc_count,
+//GO(gst_rtp_buffer_get_extension,
+//GO(gst_rtp_buffer_get_extension_bytes,
+//GO(gst_rtp_buffer_get_extension_data,
+//GO(gst_rtp_buffer_get_extension_onebyte_header,
+//GO(gst_rtp_buffer_get_extension_onebyte_header_from_bytes,
+//GO(gst_rtp_buffer_get_extension_twobytes_header,
+//GO(gst_rtp_buffer_get_header_len,
+//GO(gst_rtp_buffer_get_marker,
+//GO(gst_rtp_buffer_get_packet_len,
+//GO(gst_rtp_buffer_get_padding,
+//GO(gst_rtp_buffer_get_payload,
+//GO(gst_rtp_buffer_get_payload_buffer,
+//GO(gst_rtp_buffer_get_payload_bytes,
+//GO(gst_rtp_buffer_get_payload_len,
+//GO(gst_rtp_buffer_get_payload_subbuffer,
+//GO(gst_rtp_buffer_get_payload_type,
+//GO(gst_rtp_buffer_get_seq,
+//GO(gst_rtp_buffer_get_ssrc,
+//GO(gst_rtp_buffer_get_timestamp,
+//GO(gst_rtp_buffer_get_version,
+//GO(gst_rtp_buffer_map,
+GO(gst_rtp_buffer_map_flags_get_type, LFv)
+//GO(gst_rtp_buffer_new_allocate,
+//GO(gst_rtp_buffer_new_allocate_len,
+//GO(gst_rtp_buffer_new_copy_data,
+//GO(gst_rtp_buffer_new_take_data,
+//GO(gst_rtp_buffer_pad_to,
+//GO(gst_rtp_buffer_remove_extension_data,
+//GO(gst_rtp_buffer_set_csrc,
+//GO(gst_rtp_buffer_set_extension,
+//GO(gst_rtp_buffer_set_extension_data,
+//GO(gst_rtp_buffer_set_marker,
+//GO(gst_rtp_buffer_set_packet_len,
+//GO(gst_rtp_buffer_set_padding,
+//GO(gst_rtp_buffer_set_payload_type,
+//GO(gst_rtp_buffer_set_seq,
+//GO(gst_rtp_buffer_set_ssrc,
+//GO(gst_rtp_buffer_set_timestamp,
+//GO(gst_rtp_buffer_set_version,
+//GO(gst_rtp_buffer_unmap,
+//GO(gst_rtp_get_header_extension_list,
+//GO(gst_rtp_hdrext_get_ntp_56,
+//GO(gst_rtp_hdrext_get_ntp_64,
+//GO(gst_rtp_hdrext_set_ntp_56,
+//GO(gst_rtp_hdrext_set_ntp_64,
+//GO(gst_rtp_header_extension_class_set_uri,
+//GO(gst_rtp_header_extension_create_from_uri,
+GO(gst_rtp_header_extension_direction_get_type, LFv)
+GO(gst_rtp_header_extension_flags_get_type, LFv)
+//GO(gst_rtp_header_extension_get_direction,
+//GO(gst_rtp_header_extension_get_id,
+//GO(gst_rtp_header_extension_get_max_size,
+//GO(gst_rtp_header_extension_get_sdp_caps_field_name,
+//GO(gst_rtp_header_extension_get_supported_flags,
+GO(gst_rtp_header_extension_get_type, LFv)
+//GO(gst_rtp_header_extension_get_uri,
+//GO(gst_rtp_header_extension_read,
+//GO(gst_rtp_header_extension_set_attributes_from_caps,
+//GO(gst_rtp_header_extension_set_caps_from_attributes,
+//GO(gst_rtp_header_extension_set_caps_from_attributes_helper,
+//GO(gst_rtp_header_extension_set_direction,
+//GO(gst_rtp_header_extension_set_id,
+//GO(gst_rtp_header_extension_set_non_rtp_sink_caps,
+//GO(gst_rtp_header_extension_set_wants_update_non_rtp_src_caps,
+//GO(gst_rtp_header_extension_update_non_rtp_src_caps,
+//GO(gst_rtp_header_extension_wants_update_non_rtp_src_caps,
+//GO(gst_rtp_header_extension_write,
+GO(gst_rtp_payload_get_type, LFv)
+//GO(gst_rtp_payload_info_for_name,
+//GO(gst_rtp_payload_info_for_pt,
+GO(gst_rtp_profile_get_type, LFv)
+GO(gst_rtp_source_meta_api_get_type, LFv)
+//GO(gst_rtp_source_meta_append_csrc,
+//GO(gst_rtp_source_meta_get_info,
+//GO(gst_rtp_source_meta_get_source_count,
+//GO(gst_rtp_source_meta_set_ssrc,
diff --git a/src/wrapped/wrappedgstrtsp.c b/src/wrapped/wrappedgstrtsp.c
new file mode 100644
index 0000000..57d45ac
--- /dev/null
+++ b/src/wrapped/wrappedgstrtsp.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstrtspName = "libgstrtsp-1.0.so";
+#else
+ const char* gstrtspName = "libgstrtsp-1.0.so.0";
+#endif
+
+#define LIBNAME gstrtsp
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstrtsp_private.h b/src/wrapped/wrappedgstrtsp_private.h
new file mode 100644
index 0000000..f9d9ebf
--- /dev/null
+++ b/src/wrapped/wrappedgstrtsp_private.h
@@ -0,0 +1,170 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(gst_rtsp_auth_credential_get_type, LFv)
+//GO(gst_rtsp_auth_credentials_free,
+GO(gst_rtsp_auth_method_get_type, LFv)
+//GO(gst_rtsp_auth_param_copy,
+//GO(gst_rtsp_auth_param_free,
+GO(gst_rtsp_auth_param_get_type, LFv)
+//GO(gst_rtsp_connection_accept,
+//GO(gst_rtsp_connection_clear_auth_params,
+//GO(gst_rtsp_connection_close,
+//GO(gst_rtsp_connection_connect,
+//GO(gst_rtsp_connection_connect_usec,
+//GO(gst_rtsp_connection_connect_with_response,
+//GO(gst_rtsp_connection_connect_with_response_usec,
+//GO(gst_rtsp_connection_create,
+//GO(gst_rtsp_connection_create_from_socket,
+//GO(gst_rtsp_connection_do_tunnel,
+//GO(gst_rtsp_connection_flush,
+//GO(gst_rtsp_connection_free,
+//GO(gst_rtsp_connection_get_ignore_x_server_reply,
+//GO(gst_rtsp_connection_get_ip,
+//GO(gst_rtsp_connection_get_read_socket,
+//GO(gst_rtsp_connection_get_remember_session_id,
+//GO(gst_rtsp_connection_get_tls,
+//GO(gst_rtsp_connection_get_tls_database,
+//GO(gst_rtsp_connection_get_tls_interaction,
+//GO(gst_rtsp_connection_get_tls_validation_flags,
+//GO(gst_rtsp_connection_get_tunnelid,
+//GO(gst_rtsp_connection_get_url,
+//GO(gst_rtsp_connection_get_write_socket,
+//GO(gst_rtsp_connection_is_tunneled,
+//GO(gst_rtsp_connection_next_timeout,
+//GO(gst_rtsp_connection_next_timeout_usec,
+//GO(gst_rtsp_connection_poll,
+//GO(gst_rtsp_connection_poll_usec,
+//GO(gst_rtsp_connection_read,
+//GO(gst_rtsp_connection_read_usec,
+//GO(gst_rtsp_connection_receive,
+//GO(gst_rtsp_connection_receive_usec,
+//GO(gst_rtsp_connection_reset_timeout,
+//GO(gst_rtsp_connection_send,
+//GO(gst_rtsp_connection_send_messages,
+//GO(gst_rtsp_connection_send_messages_usec,
+//GO(gst_rtsp_connection_send_usec,
+//GO(gst_rtsp_connection_set_accept_certificate_func,
+//GO(gst_rtsp_connection_set_auth,
+//GO(gst_rtsp_connection_set_auth_param,
+//GO(gst_rtsp_connection_set_content_length_limit,
+//GO(gst_rtsp_connection_set_http_mode,
+//GO(gst_rtsp_connection_set_ignore_x_server_reply,
+//GO(gst_rtsp_connection_set_ip,
+//GO(gst_rtsp_connection_set_proxy,
+//GO(gst_rtsp_connection_set_qos_dscp,
+//GO(gst_rtsp_connection_set_remember_session_id,
+//GO(gst_rtsp_connection_set_tls_database,
+//GO(gst_rtsp_connection_set_tls_interaction,
+//GO(gst_rtsp_connection_set_tls_validation_flags,
+//GO(gst_rtsp_connection_set_tunneled,
+//GO(gst_rtsp_connection_write,
+//GO(gst_rtsp_connection_write_usec,
+GO(gst_rtsp_event_get_type, LFv)
+//GO(gst_rtsp_extension_after_send,
+//GO(gst_rtsp_extension_before_send,
+//GO(gst_rtsp_extension_configure_stream,
+//GO(gst_rtsp_extension_detect_server,
+//GO(gst_rtsp_extension_get_transports,
+GO(gst_rtsp_extension_get_type, LFv)
+//GO(gst_rtsp_extension_parse_sdp,
+//GO(gst_rtsp_extension_receive_request,
+//GO(gst_rtsp_extension_send,
+//GO(gst_rtsp_extension_setup_media,
+//GO(gst_rtsp_extension_stream_select,
+GO(gst_rtsp_family_get_type, LFv)
+//GO(gst_rtsp_find_header_field,
+//GO(gst_rtsp_find_method,
+//GO(gst_rtsp_generate_digest_auth_response,
+//GO(gst_rtsp_generate_digest_auth_response_from_md5,
+//GO(gst_rtsp_header_allow_multiple,
+//GO(gst_rtsp_header_as_text,
+GO(gst_rtsp_header_field_get_type, LFv)
+GO(gst_rtsp_lower_trans_get_type, LFv)
+//GO(gst_rtsp_message_add_header,
+//GO(gst_rtsp_message_add_header_by_name,
+//GO(gst_rtsp_message_append_headers,
+//GO(gst_rtsp_message_copy,
+//GO(gst_rtsp_message_dump,
+//GO(gst_rtsp_message_free,
+//GO(gst_rtsp_message_get_body,
+//GO(gst_rtsp_message_get_body_buffer,
+//GO(gst_rtsp_message_get_header,
+//GO(gst_rtsp_message_get_header_by_name,
+GO(gst_rtsp_message_get_type, LFv)
+//GO(gst_rtsp_message_has_body_buffer,
+//GO(gst_rtsp_message_init,
+//GO(gst_rtsp_message_init_data,
+//GO(gst_rtsp_message_init_request,
+//GO(gst_rtsp_message_init_response,
+//GO(gst_rtsp_message_new,
+//GO(gst_rtsp_message_new_data,
+//GO(gst_rtsp_message_new_request,
+//GO(gst_rtsp_message_new_response,
+//GO(gst_rtsp_message_parse_auth_credentials,
+//GO(gst_rtsp_message_parse_data,
+//GO(gst_rtsp_message_parse_request,
+//GO(gst_rtsp_message_parse_response,
+//GO(gst_rtsp_message_remove_header,
+//GO(gst_rtsp_message_remove_header_by_name,
+//GO(gst_rtsp_message_set_body,
+//GO(gst_rtsp_message_set_body_buffer,
+//GO(gst_rtsp_message_steal_body,
+//GO(gst_rtsp_message_steal_body_buffer,
+//GO(gst_rtsp_message_take_body,
+//GO(gst_rtsp_message_take_body_buffer,
+//GO(gst_rtsp_message_take_header,
+//GO(gst_rtsp_message_take_header_by_name,
+//GO(gst_rtsp_message_unset,
+//GO(gst_rtsp_method_as_text,
+GO(gst_rtsp_method_get_type, LFv)
+GO(gst_rtsp_msg_get_type, LFv)
+GO(gst_rtsp_msg_type_get_type, LFv)
+//GO(gst_rtsp_options_as_text,
+//GO(gst_rtsp_options_from_text,
+GO(gst_rtsp_profile_get_type, LFv)
+//GO(gst_rtsp_range_convert_units,
+//GO(gst_rtsp_range_free,
+//GO(gst_rtsp_range_get_times,
+//GO(gst_rtsp_range_parse,
+//GO(gst_rtsp_range_to_string,
+GO(gst_rtsp_range_unit_get_type, LFv)
+GO(gst_rtsp_result_get_type, LFv)
+GO(gst_rtsp_state_get_type, LFv)
+//GO(gst_rtsp_status_as_text,
+GO(gst_rtsp_status_code_get_type, LFv)
+//GO(gst_rtsp_strresult,
+GO(gst_rtsp_time_type_get_type, LFv)
+GO(gst_rtsp_trans_mode_get_type, LFv)
+//GO(gst_rtsp_transport_as_text,
+//GO(gst_rtsp_transport_free,
+//GO(gst_rtsp_transport_get_manager,
+//GO(gst_rtsp_transport_get_media_type,
+//GO(gst_rtsp_transport_get_mime,
+//GO(gst_rtsp_transport_init,
+//GO(gst_rtsp_transport_new,
+//GO(gst_rtsp_transport_parse,
+//GO(gst_rtsp_url_copy,
+//GO(gst_rtsp_url_decode_path_components,
+//GO(gst_rtsp_url_free,
+//GO(gst_rtsp_url_get_port,
+//GO(gst_rtsp_url_get_request_uri,
+//GO(gst_rtsp_url_get_request_uri_with_control,
+GO(gst_rtsp_url_get_type, LFv)
+//GO(gst_rtsp_url_parse,
+//GO(gst_rtsp_url_set_port,
+//GO(gst_rtsp_version_as_text,
+GO(gst_rtsp_version_get_type, LFv)
+//GO(gst_rtsp_watch_attach,
+//GO(gst_rtsp_watch_get_send_backlog,
+//GO(gst_rtsp_watch_new,
+//GO(gst_rtsp_watch_reset,
+//GO(gst_rtsp_watch_send_message,
+//GO(gst_rtsp_watch_send_messages,
+//GO(gst_rtsp_watch_set_flushing,
+//GO(gst_rtsp_watch_set_send_backlog,
+//GO(gst_rtsp_watch_unref,
+//GO(gst_rtsp_watch_wait_backlog,
+//GO(gst_rtsp_watch_wait_backlog_usec,
+//GO(gst_rtsp_watch_write_data,
diff --git a/src/wrapped/wrappedgstsdp.c b/src/wrapped/wrappedgstsdp.c
new file mode 100644
index 0000000..ddda7d1
--- /dev/null
+++ b/src/wrapped/wrappedgstsdp.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+#ifdef ANDROID
+ const char* gstsdpName = "libgstsdp-1.0.so";
+#else
+ const char* gstsdpName = "libgstsdp-1.0.so.0";
+#endif
+
+#define LIBNAME gstsdp
+
+#define PRE_INIT \
+ if(box64_nogtk) \
+ return -1;
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstsdp_private.h b/src/wrapped/wrappedgstsdp_private.h
new file mode 100644
index 0000000..ba88728
--- /dev/null
+++ b/src/wrapped/wrappedgstsdp_private.h
@@ -0,0 +1,178 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+//GO(gst_mikey_message_add_cs_srtp,
+//GO(gst_mikey_message_add_payload,
+//GO(gst_mikey_message_add_pke,
+//GO(gst_mikey_message_add_rand,
+//GO(gst_mikey_message_add_rand_len,
+//GO(gst_mikey_message_add_t,
+//GO(gst_mikey_message_add_t_now_ntp_utc,
+//GO(gst_mikey_message_base64_encode,
+//GO(gst_mikey_message_find_payload,
+//GO(gst_mikey_message_get_cs_srtp,
+//GO(gst_mikey_message_get_n_cs,
+//GO(gst_mikey_message_get_n_payloads,
+//GO(gst_mikey_message_get_payload,
+GO(gst_mikey_message_get_type, LFv)
+//GO(gst_mikey_message_insert_cs_srtp,
+//GO(gst_mikey_message_insert_payload,
+//GO(gst_mikey_message_new,
+//GO(gst_mikey_message_new_from_bytes,
+//GO(gst_mikey_message_new_from_caps,
+//GO(gst_mikey_message_new_from_data,
+//GO(gst_mikey_message_remove_cs_srtp,
+//GO(gst_mikey_message_remove_payload,
+//GO(gst_mikey_message_replace_cs_srtp,
+//GO(gst_mikey_message_replace_payload,
+//GO(gst_mikey_message_set_info,
+//GO(gst_mikey_message_to_bytes,
+//GO(gst_mikey_message_to_caps,
+GO(gst_mikey_payload_get_type, LFv)
+//GO(gst_mikey_payload_kemac_add_sub,
+//GO(gst_mikey_payload_kemac_get_n_sub,
+//GO(gst_mikey_payload_kemac_get_sub,
+//GO(gst_mikey_payload_kemac_remove_sub,
+//GO(gst_mikey_payload_kemac_set,
+//GO(gst_mikey_payload_key_data_set_interval,
+//GO(gst_mikey_payload_key_data_set_key,
+//GO(gst_mikey_payload_key_data_set_salt,
+//GO(gst_mikey_payload_key_data_set_spi,
+//GO(gst_mikey_payload_new,
+//GO(gst_mikey_payload_pke_set,
+//GO(gst_mikey_payload_rand_set,
+//GO(gst_mikey_payload_sp_add_param,
+//GO(gst_mikey_payload_sp_get_n_params,
+//GO(gst_mikey_payload_sp_get_param,
+//GO(gst_mikey_payload_sp_remove_param,
+//GO(gst_mikey_payload_sp_set,
+//GO(gst_mikey_payload_t_set,
+//GO(gst_sdp_address_is_multicast,
+//GO(gst_sdp_attribute_clear,
+//GO(gst_sdp_attribute_set,
+//GO(gst_sdp_bandwidth_clear,
+//GO(gst_sdp_bandwidth_set,
+//GO(gst_sdp_connection_clear,
+//GO(gst_sdp_connection_set,
+//GO(gst_sdp_make_keymgmt,
+//GO(gst_sdp_media_add_attribute,
+//GO(gst_sdp_media_add_bandwidth,
+//GO(gst_sdp_media_add_connection,
+//GO(gst_sdp_media_add_format,
+//GO(gst_sdp_media_as_text,
+//GO(gst_sdp_media_attributes_len,
+//GO(gst_sdp_media_attributes_to_caps,
+//GO(gst_sdp_media_bandwidths_len,
+//GO(gst_sdp_media_connections_len,
+//GO(gst_sdp_media_copy,
+//GO(gst_sdp_media_formats_len,
+//GO(gst_sdp_media_free,
+//GO(gst_sdp_media_get_attribute,
+//GO(gst_sdp_media_get_attribute_val,
+//GO(gst_sdp_media_get_attribute_val_n,
+//GO(gst_sdp_media_get_bandwidth,
+//GO(gst_sdp_media_get_caps_from_media,
+//GO(gst_sdp_media_get_connection,
+//GO(gst_sdp_media_get_format,
+//GO(gst_sdp_media_get_information,
+//GO(gst_sdp_media_get_key,
+//GO(gst_sdp_media_get_media,
+//GO(gst_sdp_media_get_num_ports,
+//GO(gst_sdp_media_get_port,
+//GO(gst_sdp_media_get_proto,
+//GO(gst_sdp_media_init,
+//GO(gst_sdp_media_insert_attribute,
+//GO(gst_sdp_media_insert_bandwidth,
+//GO(gst_sdp_media_insert_connection,
+//GO(gst_sdp_media_insert_format,
+//GO(gst_sdp_media_new,
+//GO(gst_sdp_media_parse_keymgmt,
+//GO(gst_sdp_media_remove_attribute,
+//GO(gst_sdp_media_remove_bandwidth,
+//GO(gst_sdp_media_remove_connection,
+//GO(gst_sdp_media_remove_format,
+//GO(gst_sdp_media_replace_attribute,
+//GO(gst_sdp_media_replace_bandwidth,
+//GO(gst_sdp_media_replace_connection,
+//GO(gst_sdp_media_replace_format,
+//GO(gst_sdp_media_set_information,
+//GO(gst_sdp_media_set_key,
+//GO(gst_sdp_media_set_media,
+//GO(gst_sdp_media_set_media_from_caps,
+//GO(gst_sdp_media_set_port_info,
+//GO(gst_sdp_media_set_proto,
+//GO(gst_sdp_media_uninit,
+//GO(gst_sdp_message_add_attribute,
+//GO(gst_sdp_message_add_bandwidth,
+//GO(gst_sdp_message_add_email,
+//GO(gst_sdp_message_add_media,
+//GO(gst_sdp_message_add_phone,
+//GO(gst_sdp_message_add_time,
+//GO(gst_sdp_message_add_zone,
+//GO(gst_sdp_message_as_text,
+//GO(gst_sdp_message_as_uri,
+//GO(gst_sdp_message_attributes_len,
+//GO(gst_sdp_message_attributes_to_caps,
+//GO(gst_sdp_message_bandwidths_len,
+//GO(gst_sdp_message_copy,
+//GO(gst_sdp_message_dump,
+//GO(gst_sdp_message_emails_len,
+//GO(gst_sdp_message_free,
+//GO(gst_sdp_message_get_attribute,
+//GO(gst_sdp_message_get_attribute_val,
+//GO(gst_sdp_message_get_attribute_val_n,
+//GO(gst_sdp_message_get_bandwidth,
+//GO(gst_sdp_message_get_connection,
+//GO(gst_sdp_message_get_email,
+//GO(gst_sdp_message_get_information,
+//GO(gst_sdp_message_get_key,
+//GO(gst_sdp_message_get_media,
+//GO(gst_sdp_message_get_origin,
+//GO(gst_sdp_message_get_phone,
+//GO(gst_sdp_message_get_session_name,
+//GO(gst_sdp_message_get_time,
+GO(gst_sdp_message_get_type, LFv)
+//GO(gst_sdp_message_get_uri,
+//GO(gst_sdp_message_get_version,
+//GO(gst_sdp_message_get_zone,
+//GO(gst_sdp_message_init,
+//GO(gst_sdp_message_insert_attribute,
+//GO(gst_sdp_message_insert_bandwidth,
+//GO(gst_sdp_message_insert_email,
+//GO(gst_sdp_message_insert_phone,
+//GO(gst_sdp_message_insert_time,
+//GO(gst_sdp_message_insert_zone,
+//GO(gst_sdp_message_medias_len,
+//GO(gst_sdp_message_new,
+//GO(gst_sdp_message_new_from_text,
+//GO(gst_sdp_message_parse_buffer,
+//GO(gst_sdp_message_parse_keymgmt,
+//GO(gst_sdp_message_parse_uri,
+//GO(gst_sdp_message_phones_len,
+//GO(gst_sdp_message_remove_attribute,
+//GO(gst_sdp_message_remove_bandwidth,
+//GO(gst_sdp_message_remove_email,
+//GO(gst_sdp_message_remove_phone,
+//GO(gst_sdp_message_remove_time,
+//GO(gst_sdp_message_remove_zone,
+//GO(gst_sdp_message_replace_attribute,
+//GO(gst_sdp_message_replace_bandwidth,
+//GO(gst_sdp_message_replace_email,
+//GO(gst_sdp_message_replace_phone,
+//GO(gst_sdp_message_replace_time,
+//GO(gst_sdp_message_replace_zone,
+//GO(gst_sdp_message_set_connection,
+//GO(gst_sdp_message_set_information,
+//GO(gst_sdp_message_set_key,
+//GO(gst_sdp_message_set_origin,
+//GO(gst_sdp_message_set_session_name,
+//GO(gst_sdp_message_set_uri,
+//GO(gst_sdp_message_set_version,
+//GO(gst_sdp_message_times_len,
+//GO(gst_sdp_message_uninit,
+//GO(gst_sdp_message_zones_len,
+//GO(gst_sdp_time_clear,
+//GO(gst_sdp_time_set,
+//GO(gst_sdp_zone_clear,
+//GO(gst_sdp_zone_set,
diff --git a/src/wrapped/wrappedgsttag.c b/src/wrapped/wrappedgsttag.c
index a67f405..f7aad56 100644
--- a/src/wrapped/wrappedgsttag.c
+++ b/src/wrapped/wrappedgsttag.c
@@ -12,7 +12,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* gsttagName = "libgsttag-1.0.so.0";
+#ifdef ANDROID
+ const char* gsttagName = "libgsttag-1.0.so";
+#else
+ const char* gsttagName = "libgsttag-1.0.so.0";
+#endif
+
#define LIBNAME gsttag
#define PRE_INIT \
diff --git a/src/wrapped/wrappedgsttag_private.h b/src/wrapped/wrappedgsttag_private.h
index 26e284a..9049c9e 100644
--- a/src/wrapped/wrappedgsttag_private.h
+++ b/src/wrapped/wrappedgsttag_private.h
@@ -5,7 +5,7 @@
//GO(gst_tag_check_language_code,
//GO(gst_tag_demux_get_type,
//GO(gst_tag_demux_result_get_type,
-//GO(gst_tag_freeform_string_to_utf8,
+GO(gst_tag_freeform_string_to_utf8, pFpip)
//GO(gst_tag_from_id3_tag,
//GO(gst_tag_from_id3_user_tag,
//GO(gst_tag_from_vorbis_tag,
@@ -24,15 +24,15 @@ GO(gst_tag_get_language_name, pFp)
//GO(gst_tag_get_license_version,
//GO(gst_tag_id3_genre_count,
//GO(gst_tag_id3_genre_get,
-//GO(gst_tag_image_data_to_image_sample,
+GO(gst_tag_image_data_to_image_sample, pFpui)
//GO(gst_tag_image_type_get_type,
//GO(gst_tag_license_flags_get_type,
//GO(gst_tag_list_add_id3_image,
//GO(gst_tag_list_from_exif_buffer,
//GO(gst_tag_list_from_exif_buffer_with_tiff_header,
//GO(gst_tag_list_from_id3v2_tag,
-//GO(gst_tag_list_from_vorbiscomment,
-//GO(gst_tag_list_from_vorbiscomment_buffer,
+GO(gst_tag_list_from_vorbiscomment, pFpLpup)
+GO(gst_tag_list_from_vorbiscomment_buffer, pFppup)
//GO(gst_tag_list_from_xmp_buffer,
//GO(gst_tag_list_new_from_id3v1,
//GO(gst_tag_list_to_exif_buffer,
diff --git a/src/wrapped/wrappedgstvideo.c b/src/wrapped/wrappedgstvideo.c
index 7bb08d7..ef63ce4 100644
--- a/src/wrapped/wrappedgstvideo.c
+++ b/src/wrapped/wrappedgstvideo.c
@@ -11,12 +11,64 @@
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+#include "gtkclass.h"
+#include "fileutils.h"
+
+#ifdef ANDROID
+ const char* gstvideoName = "libgstvideo-1.0.so";
+#else
+ const char* gstvideoName = "libgstvideo-1.0.so.0";
+#endif
-const char* gstvideoName = "libgstvideo-1.0.so.0";
#define LIBNAME gstvideo
+typedef size_t (*LFv_t)();
+
+#define ADDED_FUNCTIONS() \
+ GO(gst_video_decoder_get_type, LFv_t) \
+ GO(gst_video_encoder_get_type, LFv_t) \
+ GO(gst_video_sink_get_type, LFv_t) \
+ GO(gst_video_aggregator_get_type, LFv_t) \
+ GO(gst_video_aggregator_pad_get_type, LFv_t) \
+ GO(gst_video_filter_get_type, LFv_t) \
+
+#include "generated/wrappedgstbasetypes.h"
+
+#include "wrappercallback.h"
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstVideoDecoderID(my->gst_video_decoder_get_type());\
+ SetGstVideoEncoderID(my->gst_video_encoder_get_type());\
+ SetGstVideoSinkID(my->gst_video_sink_get_type());\
+ SetGstVideoAggregatorID(my->gst_video_aggregator_get_type());\
+ SetGstVideoAggregatorPadID(my->gst_video_aggregator_pad_get_type());\
+ SetGstVideoFilterID(my->gst_video_filter_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ SetGstVideoDecoderID(my->gst_video_decoder_get_type());\
+ SetGstVideoEncoderID(my->gst_video_encoder_get_type());\
+ SetGstVideoSinkID(my->gst_video_sink_get_type());\
+ SetGstVideoAggregatorID(my->gst_video_aggregator_get_type());\
+ SetGstVideoAggregatorPadID(my->gst_video_aggregator_pad_get_type());\
+ SetGstVideoFilterID(my->gst_video_filter_get_type());\
+ setNeededLibs(lib, 1, "libgstreamer-1.0.so.0");
+#endif
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedgstvideo_private.h b/src/wrapped/wrappedgstvideo_private.h
index 27eb4ae..56d6647 100644
--- a/src/wrapped/wrappedgstvideo_private.h
+++ b/src/wrapped/wrappedgstvideo_private.h
@@ -3,44 +3,53 @@
#endif
//GO(gst_buffer_add_video_afd_meta,
-//GO(gst_buffer_add_video_affine_transformation_meta,
+GO(gst_buffer_add_video_affine_transformation_meta, pFp)
//GO(gst_buffer_add_video_bar_meta,
-//GO(gst_buffer_add_video_caption_meta,
+GO(gst_buffer_add_video_caption_meta, pFpipL)
+GO(gst_buffer_add_video_codec_alpha_meta, pFpp)
//GO(gst_buffer_add_video_gl_texture_upload_meta,
-//GO(gst_buffer_add_video_meta,
-//GO(gst_buffer_add_video_meta_full,
+GO(gst_buffer_add_video_meta, pFpiiuu)
+GO(gst_buffer_add_video_meta_full, pFpiiuuupp)
//GO(gst_buffer_add_video_overlay_composition_meta,
//GO(gst_buffer_add_video_region_of_interest_meta,
//GO(gst_buffer_add_video_region_of_interest_meta_id,
-//GO(gst_buffer_add_video_time_code_meta,
+GO(gst_buffer_add_video_time_code_meta, pFpp)
//GO(gst_buffer_add_video_time_code_meta_full,
-//GO(gst_buffer_get_video_meta,
+GO(gst_buffer_get_video_meta, pFp)
//GO(gst_buffer_get_video_meta_id,
//GO(gst_buffer_get_video_region_of_interest_meta_id,
GO(gst_buffer_pool_config_get_video_alignment, iFpp)
GO(gst_buffer_pool_config_set_video_alignment, vFpp)
-//GO(gst_color_balance_channel_get_type,
+GO(gst_color_balance_channel_get_type, LFv)
GO(gst_color_balance_get_balance_type, uFp)
-//GO(gst_color_balance_get_type,
+GO(gst_color_balance_get_type, LFv)
GO(gst_color_balance_get_value, iFpp)
GO(gst_color_balance_list_channels, pFp)
-//GO(gst_color_balance_set_value,
+GO(gst_color_balance_set_value, vFppi)
//GO(gst_color_balance_type_get_type,
GO(gst_color_balance_value_changed, vFppi)
//GO(gst_is_video_overlay_prepare_window_handle_message,
//GO(gst_navigation_command_get_type,
-//GO(gst_navigation_event_get_type,
+GO(gst_navigation_event_get_coordinates, iFppp)
+GO(gst_navigation_event_get_type, LFv)
+GO(gst_navigation_event_new_key_press, pFpi)
+GO(gst_navigation_event_new_key_release, pFpi)
+GO(gst_navigation_event_new_mouse_button_press, pFpddi)
+GO(gst_navigation_event_new_mouse_button_release, pFpddi)
+GO(gst_navigation_event_new_mouse_move, pFddi)
+GO(gst_navigation_event_new_mouse_scroll, pFddddi)
//GO(gst_navigation_event_parse_command,
-//GO(gst_navigation_event_parse_key_event,
+GO(gst_navigation_event_parse_key_event, iFpp)
//GO(gst_navigation_event_parse_mouse_button_event,
//GO(gst_navigation_event_parse_mouse_move_event,
-//GO(gst_navigation_event_parse_mouse_scroll_event,
+GO(gst_navigation_event_parse_mouse_scroll_event, iFppppp)
+GO(gst_navigation_event_set_coordinates, iFpdd)
//GO(gst_navigation_event_type_get_type,
-//GO(gst_navigation_get_type,
+GO(gst_navigation_get_type, LFv)
//GO(gst_navigation_message_get_type,
//GO(gst_navigation_message_new_angles_changed,
//GO(gst_navigation_message_new_commands_changed,
-//GO(gst_navigation_message_new_event,
+GO(gst_navigation_message_new_event, pFpp)
//GO(gst_navigation_message_new_mouse_over,
//GO(gst_navigation_message_parse_angles_changed,
//GO(gst_navigation_message_parse_event,
@@ -55,136 +64,140 @@ GO(gst_color_balance_value_changed, vFppi)
//GO(gst_navigation_query_set_angles,
//GO(gst_navigation_query_set_commands,
//GO(gst_navigation_query_set_commandsv,
-//GO(gst_navigation_query_type_get_type,
+GO(gst_navigation_query_type_get_type, LFv)
GO(gst_navigation_send_command, vFpu)
GO(gst_navigation_send_event, vFpp)
+GO(gst_navigation_send_event_simple, vFpp)
GO(gst_navigation_send_key_event, vFppp)
GO(gst_navigation_send_mouse_event, vFppidd)
GO(gst_navigation_send_mouse_scroll_event, vFpdddd)
-//GO(gst_video_afd_meta_api_get_type,
+GO(gst_video_afd_meta_api_get_type, LFv)
//GO(gst_video_afd_meta_get_info,
-//GO(gst_video_afd_spec_get_type,
-//GO(gst_video_afd_value_get_type,
-//GO(gst_video_affine_transformation_meta_api_get_type,
+GO(gst_video_afd_spec_get_type, LFv)
+GO(gst_video_afd_value_get_type, LFv)
+GO(gst_video_affine_transformation_meta_api_get_type, LFv)
//GO(gst_video_affine_transformation_meta_apply_matrix,
//GO(gst_video_affine_transformation_meta_get_info,
-//GO(gst_video_aggregator_convert_pad_get_type,
+GO(gst_video_aggregator_convert_pad_get_type, LFv)
//GO(gst_video_aggregator_convert_pad_update_conversion_info,
-//GO(gst_video_aggregator_get_type,
-//GO(gst_video_aggregator_pad_get_current_buffer,
+GO(gst_video_aggregator_get_type, LFv)
+GO(gst_video_aggregator_pad_get_current_buffer, pFp)
//GO(gst_video_aggregator_pad_get_prepared_frame,
-//GO(gst_video_aggregator_pad_get_type,
+GO(gst_video_aggregator_pad_get_type, LFv)
//GO(gst_video_aggregator_pad_has_current_buffer,
//GO(gst_video_aggregator_pad_set_needs_alpha,
GO(gst_video_alignment_reset, vFp)
-//GO(gst_video_alpha_mode_get_type,
-//GO(gst_video_ancillary_di_d16_get_type,
-//GO(gst_video_ancillary_did_get_type,
-//GO(gst_video_bar_meta_api_get_type,
+GO(gst_video_alpha_mode_get_type, LFv)
+GO(gst_video_ancillary_di_d16_get_type, LFv)
+GO(gst_video_ancillary_did_get_type, LFv)
+GO(gst_video_bar_meta_api_get_type, LFv)
//GO(gst_video_bar_meta_get_info,
//GO(gst_video_blend,
//GO(gst_video_blend_scale_linear_RGBA,
-//GO(gst_video_buffer_flags_get_type,
-//GO(gst_video_buffer_pool_get_type,
+GO(gst_video_buffer_flags_get_type, LFv)
+GO(gst_video_buffer_pool_get_type, LFv)
GO(gst_video_buffer_pool_new, pFv)
GO(gst_video_calculate_display_ratio, iFppuuuuuu)
-//GO(gst_video_caption_meta_api_get_type,
+GO(gst_video_caption_meta_api_get_type, LFv)
//GO(gst_video_caption_meta_get_info,
//GO(gst_video_caption_type_from_caps,
-//GO(gst_video_caption_type_get_type,
+GO(gst_video_caption_type_get_type, LFv)
//GO(gst_video_caption_type_to_caps,
-//GO(gst_video_chroma_flags_get_type,
+GO(gst_video_chroma_flags_get_type, LFv)
//GO(gst_video_chroma_from_string,
-//GO(gst_video_chroma_method_get_type,
-//GO(gst_video_chroma_mode_get_type,
+GO(gst_video_chroma_method_get_type, LFv)
+GO(gst_video_chroma_mode_get_type, LFv)
GO(gst_video_chroma_resample, vFppi)
GO(gst_video_chroma_resample_free, vFp)
GO(gst_video_chroma_resample_get_info, vFppp)
GO(gst_video_chroma_resample_new, pFuuuuii)
-//GO(gst_video_chroma_site_get_type,
+GO(gst_video_chroma_site_get_type, LFv)
GO(gst_video_chroma_to_string, pFu)
-//GO(gst_video_codec_frame_get_type,
+GO(gst_video_codec_frame_get_type, LFv)
//GO(gst_video_codec_frame_get_user_data,
-//GO(gst_video_codec_frame_ref,
+GO(gst_video_codec_frame_ref, pFp)
//GO(gst_video_codec_frame_set_user_data,
-//GO(gst_video_codec_frame_unref,
-//GO(gst_video_codec_state_get_type,
-//GO(gst_video_codec_state_ref,
-//GO(gst_video_codec_state_unref,
+GO(gst_video_codec_frame_unref, vFp)
+GO(gst_video_codec_state_get_type, LFv)
+GO(gst_video_codec_state_ref, pFp)
+GO(gst_video_codec_state_unref, vFp)
GO(gst_video_colorimetry_from_string, iFpp)
GO(gst_video_colorimetry_is_equal, iFpp)
GO(gst_video_colorimetry_matches, iFpp)
GO(gst_video_colorimetry_to_string, pFp)
GO(gst_video_color_matrix_from_iso, uFu)
GO(gst_video_color_matrix_get_Kr_Kb, iFupp)
-//GO(gst_video_color_matrix_get_type,
+GO(gst_video_color_matrix_get_type, LFv)
GO(gst_video_color_matrix_to_iso, uFu)
GO(gst_video_color_primaries_from_iso, uFu)
GO(gst_video_color_primaries_get_info, pFu)
-//GO(gst_video_color_primaries_get_type,
+GO(gst_video_color_primaries_get_type, LFv)
GO(gst_video_color_primaries_to_iso, uFu)
-//GO(gst_video_color_range_get_type,
+GO(gst_video_color_range_get_type, LFv)
//GO(gst_video_color_range_offsets,
//GO(gst_video_color_transfer_decode,
//GO(gst_video_color_transfer_encode,
-//GO(gst_video_content_light_level_add_to_caps,
+GO(gst_video_content_light_level_add_to_caps, iFpp)
//GO(gst_video_content_light_level_from_caps,
GO(gst_video_content_light_level_from_string, iFpp)
GO(gst_video_content_light_level_init, vFp)
GO(gst_video_content_light_level_to_string, pFp)
-//GO(gst_video_converter_frame,
-//GO(gst_video_converter_free,
+GO(gst_video_converter_frame, vFppp)
+GO(gst_video_converter_free, vFp)
GO(gst_video_converter_get_config, pFp)
-//GO(gst_video_converter_new,
+GO(gst_video_converter_new, pFppp)
GO(gst_video_converter_set_config, iFpp)
//GO(gst_video_convert_sample,
//GO(gst_video_convert_sample_async,
-//GO(gst_video_crop_meta_api_get_type,
-//GO(gst_video_crop_meta_get_info,
-//GO(gst_video_decoder_add_to_frame,
+GO(gst_video_crop_meta_api_get_type, LFv)
+GO(gst_video_crop_meta_get_info, pFv)
+GO(gst_video_decoder_add_to_frame, vFpi)
//GO(gst_video_decoder_allocate_output_buffer,
-//GO(gst_video_decoder_allocate_output_frame,
+GO(gst_video_decoder_allocate_output_frame, iFpp)
//GO(gst_video_decoder_allocate_output_frame_with_params,
-//GO(gst_video_decoder_drop_frame,
-//GO(_gst_video_decoder_error,
-//GO(gst_video_decoder_finish_frame,
+GO(gst_video_decoder_drop_frame, iFpp)
+GO(_gst_video_decoder_error, iFpipippppi)
+GO(gst_video_decoder_finish_frame, iFpp)
//GO(gst_video_decoder_get_allocator,
-//GO(gst_video_decoder_get_buffer_pool,
+GO(gst_video_decoder_get_buffer_pool, pFp)
//GO(gst_video_decoder_get_estimate_rate,
-//GO(gst_video_decoder_get_frame,
-//GO(gst_video_decoder_get_frames,
+GO(gst_video_decoder_get_frame, pFpi)
+GO(gst_video_decoder_get_frames, pFp)
//GO(gst_video_decoder_get_latency,
-//GO(gst_video_decoder_get_max_decode_time,
+GO(gst_video_decoder_get_max_decode_time, IFpp)
//GO(gst_video_decoder_get_max_errors,
//GO(gst_video_decoder_get_needs_format,
//GO(gst_video_decoder_get_oldest_frame,
-//GO(gst_video_decoder_get_output_state,
+GO(gst_video_decoder_get_output_state, pFp)
//GO(gst_video_decoder_get_packetized,
//GO(gst_video_decoder_get_pending_frame_size,
//GO(gst_video_decoder_get_qos_proportion,
-//GO(gst_video_decoder_get_type,
-//GO(gst_video_decoder_have_frame,
-//GO(gst_video_decoder_merge_tags,
-//GO(gst_video_decoder_negotiate,
-//GO(gst_video_decoder_proxy_getcaps,
-//GO(gst_video_decoder_release_frame,
+GO(gst_video_decoder_get_subframe_mode, iFp)
+GO(gst_video_decoder_get_type, LFv)
+GO(gst_video_decoder_have_frame, iFp)
+GO(gst_video_decoder_have_last_subframe, iFpp)
+GO(gst_video_decoder_merge_tags, vFppi)
+GO(gst_video_decoder_negotiate, iFp)
+GO(gst_video_decoder_proxy_getcaps, pFppp)
+GO(gst_video_decoder_release_frame, vFpp)
//GO(gst_video_decoder_set_estimate_rate,
-//GO(gst_video_decoder_set_interlaced_output_state,
-//GO(gst_video_decoder_set_latency,
+GO(gst_video_decoder_set_interlaced_output_state, pFpiiuup)
+GO(gst_video_decoder_set_latency, vFpUU)
//GO(gst_video_decoder_set_max_errors,
-//GO(gst_video_decoder_set_needs_format,
-//GO(gst_video_decoder_set_output_state,
-//GO(gst_video_decoder_set_packetized,
-//GO(gst_video_decoder_set_use_default_pad_acceptcaps,
-//GO(gst_video_direction_get_type,
+GO(gst_video_decoder_set_needs_format, vFpi)
+GO(gst_video_decoder_set_output_state, pFpiuup)
+GO(gst_video_decoder_set_packetized, vFpi)
+GO(gst_video_decoder_set_subframe_mode, vFpi)
+GO(gst_video_decoder_set_use_default_pad_acceptcaps, vFpi)
+GO(gst_video_direction_get_type, LFv)
//GO(gst_video_dither_flags_get_type,
GO(gst_video_dither_free, vFp)
GO(gst_video_dither_line, vFppuuu)
-//GO(gst_video_dither_method_get_type,
+GO(gst_video_dither_method_get_type, LFv)
GO(gst_video_dither_new, pFuuupu)
-//GO(gst_video_encoder_allocate_output_buffer,
-//GO(gst_video_encoder_allocate_output_frame,
-//GO(gst_video_encoder_finish_frame,
+GO(gst_video_encoder_allocate_output_buffer, pFpL)
+GO(gst_video_encoder_allocate_output_frame, iFppL)
+GO(gst_video_encoder_finish_frame, iFpp)
//GO(gst_video_encoder_finish_subframe,
//GO(gst_video_encoder_get_allocator,
//GO(gst_video_encoder_get_frame,
@@ -192,36 +205,36 @@ GO(gst_video_dither_new, pFuuupu)
//GO(gst_video_encoder_get_latency,
//GO(gst_video_encoder_get_max_encode_time,
//GO(gst_video_encoder_get_min_force_key_unit_interval,
-//GO(gst_video_encoder_get_oldest_frame,
+GO(gst_video_encoder_get_oldest_frame, pFp)
//GO(gst_video_encoder_get_output_state,
-//GO(gst_video_encoder_get_type,
+GO(gst_video_encoder_get_type, LFv)
//GO(gst_video_encoder_is_qos_enabled,
-//GO(gst_video_encoder_merge_tags,
-//GO(gst_video_encoder_negotiate,
-//GO(gst_video_encoder_proxy_getcaps,
-//GO(gst_video_encoder_set_headers,
+GO(gst_video_encoder_merge_tags, vFppi)
+GO(gst_video_encoder_negotiate, iFp)
+GO(gst_video_encoder_proxy_getcaps, pFppp)
+GO(gst_video_encoder_set_headers, vFpp)
//GO(gst_video_encoder_set_latency,
//GO(gst_video_encoder_set_min_force_key_unit_interval,
-//GO(gst_video_encoder_set_min_pts,
-//GO(gst_video_encoder_set_output_state,
+GO(gst_video_encoder_set_min_pts, vFpU)
+GO(gst_video_encoder_set_output_state, pFppp)
//GO(gst_video_encoder_set_qos_enabled,
//GO(gst_video_event_is_force_key_unit,
//GO(gst_video_event_new_downstream_force_key_unit,
//GO(gst_video_event_new_still_frame,
//GO(gst_video_event_new_upstream_force_key_unit,
//GO(gst_video_event_parse_downstream_force_key_unit,
-//GO(gst_video_event_parse_still_frame,
+GO(gst_video_event_parse_still_frame, iFpp)
//GO(gst_video_event_parse_upstream_force_key_unit,
GO(gst_video_field_order_from_string, uFp)
-GO(gst_video_field_order_get_type, pFv)
+GO(gst_video_field_order_get_type, LFv)
GO(gst_video_field_order_to_string, pFu)
-GO(gst_video_filter_get_type, pFv)
-GO(gst_video_flags_get_type, pFv)
-GO(gst_video_format_flags_get_type, pFv)
+GO(gst_video_filter_get_type, LFv)
+GO(gst_video_flags_get_type, LFv)
+GO(gst_video_format_flags_get_type, LFv)
GO(gst_video_format_from_fourcc, uFu)
GO(gst_video_format_from_masks, uFiiiuuuu)
GO(gst_video_format_from_string, uFp)
-//GO(gst_video_format_get_info,
+GO(gst_video_format_get_info, pFi)
GO(gst_video_format_get_palette, pFup)
//GO(gst_video_format_get_type,
//GO(gst_video_format_info_component,
@@ -229,14 +242,14 @@ GO(gst_video_formats_raw, pFp)
GO(gst_video_format_to_fourcc, uFu)
GO(gst_video_format_to_string, pFu)
GO(gst_video_frame_copy, iFpp)
-//GO(gst_video_frame_copy_plane,
+GO(gst_video_frame_copy_plane, iFppu)
//GO(gst_video_frame_flags_get_type,
GO(gst_video_frame_map, iFpppu)
//GO(gst_video_frame_map_flags_get_type,
//GO(gst_video_frame_map_id,
GO(gst_video_frame_unmap, vFp)
-//GO(gst_video_gamma_mode_get_type,
-//GO(gst_video_gl_texture_upload_meta_api_get_type,
+GO(gst_video_gamma_mode_get_type, LFv)
+GO(gst_video_gl_texture_upload_meta_api_get_type, LFv)
//GO(gst_video_gl_texture_upload_meta_get_info,
//GO(gst_video_gl_texture_upload_meta_upload,
GO(gst_video_guess_framerate, iFLpp)
@@ -246,7 +259,7 @@ GO(gst_video_info_convert, iFpiIip)
GO(gst_video_info_copy, pFp)
GO(gst_video_info_free, vFp)
GO(gst_video_info_from_caps, iFpp)
-GO(gst_video_info_get_type, pFv)
+GO(gst_video_info_get_type, LFv)
GO(gst_video_info_init, vFp)
GO(gst_video_info_is_equal, iFpp)
GO(gst_video_info_new, pFv)
@@ -254,28 +267,29 @@ GO(gst_video_info_set_format, iFpiuu)
GO(gst_video_info_set_interlaced_format, iFpiiuu)
GO(gst_video_info_to_caps, pFp)
GO(gst_video_interlace_mode_from_string, uFp)
-GO(gst_video_interlace_mode_get_type, pFv)
+GO(gst_video_interlace_mode_get_type, LFv)
GO(gst_video_interlace_mode_to_string, pFu)
+GO(gst_video_is_common_aspect_ratio, iFiiii)
//GO(gst_video_make_raw_caps,
//GO(gst_video_make_raw_caps_with_features,
-//GO(gst_video_mastering_display_info_add_to_caps,
+GO(gst_video_mastering_display_info_add_to_caps, iFpp)
//GO(gst_video_mastering_display_info_from_caps,
GO(gst_video_mastering_display_info_from_string, iFpp)
GO(gst_video_mastering_display_info_init, vFp)
GO(gst_video_mastering_display_info_is_equal, iFpp)
GO(gst_video_mastering_display_info_to_string, pFp)
-//GO(gst_video_matrix_mode_get_type,
-GO(gst_video_meta_api_get_type, pFv)
+GO(gst_video_matrix_mode_get_type, LFv)
+GO(gst_video_meta_api_get_type, LFv)
//GO(gst_video_meta_get_info,
//GO(gst_video_meta_get_plane_height,
//GO(gst_video_meta_get_plane_size,
//GO(gst_video_meta_map,
-//GO(gst_video_meta_set_alignment,
-GO(gst_video_meta_transform_scale_get_quark, uFv)
+GO(gst_video_meta_set_alignment, iFpi)
+GO(gst_video_meta_transform_scale_get_quark, pFv)
//GO(gst_video_meta_unmap,
-//GO(gst_video_multiview_flagset_get_type,
-//GO(gst_video_multiview_flags_get_type,
-//GO(gst_video_multiview_frame_packing_get_type,
+GO(gst_video_multiview_flagset_get_type, LFv)
+GO(gst_video_multiview_flags_get_type, LFv)
+GO(gst_video_multiview_frame_packing_get_type, LFv)
//GO(gst_video_multiview_get_doubled_height_modes,
GO(gst_video_multiview_get_doubled_size_modes, pFv)
//GO(gst_video_multiview_get_doubled_width_modes,
@@ -283,15 +297,16 @@ GO(gst_video_multiview_get_doubled_size_modes, pFv)
//GO(gst_video_multiview_get_unpacked_modes,
GO(gst_video_multiview_guess_half_aspect, iFiuuuu)
GO(gst_video_multiview_mode_from_caps_string, iFp)
-//GO(gst_video_multiview_mode_get_type,
+GO(gst_video_multiview_mode_get_type, LFv)
GO(gst_video_multiview_mode_to_caps_string, pFi)
-//GO(gst_video_multiview_video_info_change_mode,
+GO(gst_video_multiview_video_info_change_mode, vFpii)
+GO(gst_video_orientation_from_tag, iFpp)
//GO(gst_video_orientation_get_hcenter,
//GO(gst_video_orientation_get_hflip,
-//GO(gst_video_orientation_get_type,
+GO(gst_video_orientation_get_type, LFv)
GO(gst_video_orientation_get_vcenter, iFpp)
GO(gst_video_orientation_get_vflip, iFpp)
-//GO(gst_video_orientation_method_get_type,
+GO(gst_video_orientation_method_get_type, LFv)
//GO(gst_video_orientation_set_hcenter,
//GO(gst_video_orientation_set_hflip,
GO(gst_video_orientation_set_vcenter, iFpi)
@@ -301,18 +316,18 @@ GO(gst_video_overlay_composition_add_rectangle, vFpp)
//GO(gst_video_overlay_composition_copy,
GO(gst_video_overlay_composition_get_rectangle, pFpu)
GO(gst_video_overlay_composition_get_seqnum, uFp)
-//GO(gst_video_overlay_composition_get_type,
+GO(gst_video_overlay_composition_get_type, LFv)
GO(gst_video_overlay_composition_make_writable, pFp)
-//GO(gst_video_overlay_composition_meta_api_get_type,
+GO(gst_video_overlay_composition_meta_api_get_type, LFv)
//GO(gst_video_overlay_composition_meta_get_info,
GO(gst_video_overlay_composition_new, pFp)
-//GO(gst_video_overlay_composition_n_rectangles,
-//GO(gst_video_overlay_expose,
-//GO(gst_video_overlay_format_flags_get_type,
-//GO(gst_video_overlay_get_type,
+GO(gst_video_overlay_composition_n_rectangles, uFp)
+GO(gst_video_overlay_expose, vFp)
+GO(gst_video_overlay_format_flags_get_type, LFv)
+GO(gst_video_overlay_get_type, LFv)
GO(gst_video_overlay_got_window_handle, vFpL)
GO(gst_video_overlay_handle_events, vFpi)
-//GO(gst_video_overlay_install_properties,
+GO(gst_video_overlay_install_properties, vFpi)
GO(gst_video_overlay_prepare_window_handle, vFp)
GO(gst_video_overlay_rectangle_copy, pFp)
GO(gst_video_overlay_rectangle_get_flags, uFp)
@@ -325,46 +340,46 @@ GO(gst_video_overlay_rectangle_get_global_alpha, fFp)
//GO(gst_video_overlay_rectangle_get_pixels_unscaled_raw,
GO(gst_video_overlay_rectangle_get_render_rectangle, iFppppp)
GO(gst_video_overlay_rectangle_get_seqnum, uFp)
-//GO(gst_video_overlay_rectangle_get_type,
+GO(gst_video_overlay_rectangle_get_type, LFv)
//GO(gst_video_overlay_rectangle_new_raw,
GO(gst_video_overlay_rectangle_set_global_alpha, vFpf)
GO(gst_video_overlay_rectangle_set_render_rectangle, vFpiiuu)
GO(gst_video_overlay_set_property, iFpiup)
GO(gst_video_overlay_set_render_rectangle, iFpiiii)
-//GO(gst_video_overlay_set_window_handle,
-//GO(gst_video_pack_flags_get_type,
-//GO(gst_video_primaries_mode_get_type,
+GO(gst_video_overlay_set_window_handle, vFpL)
+GO(gst_video_pack_flags_get_type, LFv)
+GO(gst_video_primaries_mode_get_type, LFv)
//GO(gst_video_region_of_interest_meta_add_param,
-//GO(gst_video_region_of_interest_meta_api_get_type,
+GO(gst_video_region_of_interest_meta_api_get_type, LFv)
//GO(gst_video_region_of_interest_meta_get_info,
//GO(gst_video_region_of_interest_meta_get_param,
GO(gst_video_resampler_clear, vFp)
-//GO(gst_video_resampler_flags_get_type,
+GO(gst_video_resampler_flags_get_type, LFv)
GO(gst_video_resampler_init, iFpuuuuduup)
-//GO(gst_video_resampler_method_get_type,
+GO(gst_video_resampler_method_get_type, LFv)
GO(gst_video_scaler_2d, vFppupipiuuuu)
GO(gst_video_scaler_combine_packed_YUV, pFppuu)
-//GO(gst_video_scaler_flags_get_type,
+GO(gst_video_scaler_flags_get_type, LFv)
GO(gst_video_scaler_free, vFp)
GO(gst_video_scaler_get_coeff, pFpupp)
GO(gst_video_scaler_get_max_taps, uFp)
GO(gst_video_scaler_horizontal, vFpuppuu)
GO(gst_video_scaler_new, pFuuuuup)
GO(gst_video_scaler_vertical, vFpuppuu)
-//GO(gst_video_sink_center_rect,
-//GO(gst_video_sink_get_type,
+GO(gst_video_sink_center_rect, vFpppppi) // this is vFHHpi, with 2 GstVideoRectangle struct that are 4 ints
+GO(gst_video_sink_get_type, LFv)
GO(gst_video_tile_get_index, uFuiiii)
-//GO(gst_video_tile_mode_get_type,
-//GO(gst_video_tile_type_get_type,
+GO(gst_video_tile_mode_get_type, LFv)
+GO(gst_video_tile_type_get_type, LFv)
GO(gst_video_time_code_add_frames, vFpl)
GO(gst_video_time_code_add_interval, pFpp)
//GO(gst_video_time_code_clear,
GO(gst_video_time_code_compare, iFpp)
GO(gst_video_time_code_copy, pFp)
-//GO(gst_video_time_code_flags_get_type,
+GO(gst_video_time_code_flags_get_type, LFv)
GO(gst_video_time_code_frames_since_daily_jam, LFp)
-//GO(gst_video_time_code_free,
-//GO(gst_video_time_code_get_type,
+GO(gst_video_time_code_free, vFp)
+GO(gst_video_time_code_get_type, LFv)
GO(gst_video_time_code_increment_frame, vFp)
GO(gst_video_time_code_init, vFpuupuuuuuu)
GO(gst_video_time_code_init_from_date_time, vFpuupuu)
@@ -372,12 +387,12 @@ GO(gst_video_time_code_init_from_date_time_full, iFpuupuu)
GO(gst_video_time_code_interval_clear, vFp)
GO(gst_video_time_code_interval_copy, pFp)
//GO(gst_video_time_code_interval_free,
-//GO(gst_video_time_code_interval_get_type,
+GO(gst_video_time_code_interval_get_type, LFv)
GO(gst_video_time_code_interval_init, vFpuuuu)
GO(gst_video_time_code_interval_new, pFuuuu)
GO(gst_video_time_code_interval_new_from_string, pFp)
GO(gst_video_time_code_is_valid, iFp)
-//GO(gst_video_time_code_meta_api_get_type,
+GO(gst_video_time_code_meta_api_get_type, LFv)
//GO(gst_video_time_code_meta_get_info,
GO(gst_video_time_code_new, pFuupuuuuuu)
GO(gst_video_time_code_new_empty, pFv)
diff --git a/src/wrapped/wrappedgtk3.c b/src/wrapped/wrappedgtk3.c
index 87a7bd7..2f812af 100644
--- a/src/wrapped/wrappedgtk3.c
+++ b/src/wrapped/wrappedgtk3.c
@@ -19,7 +19,12 @@
#include "myalign.h"
#include "gtkclass.h"
-const char* gtk3Name = "libgtk-3.so.0";
+#ifdef ANDROID
+ const char* gtk3Name = "libgtk-3.so";
+#else
+ const char* gtk3Name = "libgtk-3.so.0";
+#endif
+
static char* libname = NULL;
#define LIBNAME gtk3
@@ -33,6 +38,8 @@ typedef void* (*pFpu_t)(void*, uint32_t);
typedef void* (*pFppi_t)(void*, void*, int);
typedef void* (*pFppp_t)(void*, void*, void*);
typedef int (*iFppp_t)(void*, void*, void*);
+typedef void (*vFppp_t)(void*, void*, void*);
+typedef void (*vFppA_t)(void*, void*, va_list);
typedef void (*vFpipV_t)(void*, int, void*, ...);
#define ADDED_FUNCTIONS() \
@@ -42,10 +49,12 @@ GO(gtk_application_window_get_type, LFv_t) \
GO(gtk_bin_get_type, LFv_t) \
GO(gtk_widget_get_type, LFv_t) \
GO(gtk_button_get_type, LFv_t) \
+GO(gtk_menu_button_get_type, LFv_t) \
GO(gtk_container_get_type, LFv_t) \
GO(gtk_misc_get_type, LFv_t) \
GO(gtk_label_get_type, LFv_t) \
GO(gtk_list_box_get_type, LFv_t) \
+GO(gtk_image_get_type, LFv_t) \
GO(gtk_list_box_row_get_type, LFv_t) \
GO(gtk_tree_view_get_type, LFv_t) \
GO(gtk_window_get_type, LFv_t) \
@@ -77,6 +86,8 @@ GO(g_log, vFpipV_t) \
GO(g_module_open, pFpu_t) \
GO(g_module_close, vFp_t) \
GO(gtk_tree_store_newv, pFup_t) \
+GO(gtk_widget_style_get_valist, vFppA_t) \
+GO(gtk_widget_style_get_property, vFppp_t) \
#include "generated/wrappedgtk3types.h"
@@ -752,6 +763,28 @@ EXPORT void my3_gtk_clipboard_request_text(x64emu_t* emu, void* clipboard, void*
my->gtk_clipboard_request_text(clipboard, findGtkClipboardTextReceivedFuncFct(f), data);
}
+EXPORT void my3_gtk_style_context_get(x64emu_t* emu, void* context, uint32_t flags, uintptr_t* b)
+{
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 2);
+ my->gtk_style_context_get_valist(context, flags, VARARGS);
+}
+
+EXPORT void my3_gtk_widget_style_get(x64emu_t* emu, void* widget, void* first, uintptr_t* b)
+{
+ #ifdef PREFER_CONVERT_VAARG
+ CREATE_VALIST_FROM_VAARG(b, emu->scratch, 2);
+ my->gtk_widget_style_get_valist(widget, first, VARARGS);
+ #else
+ void* prop = first;
+ int i=0;
+ do {
+ void* val = (void*)getVArgs(emu, 2, b, i++);
+ my->gtk_widget_style_get_property(widget, prop, val);
+ prop = (void*)getVArgs(emu, 2, b, i++);
+ } while (prop);
+ #endif
+}
+
#define PRE_INIT \
if(box64_nogtk) \
return -1;
@@ -762,9 +795,11 @@ EXPORT void my3_gtk_clipboard_request_text(x64emu_t* emu, void* clipboard, void*
SETALT(my3_); \
SetGtkApplicationID(my->gtk_application_get_type()); \
SetGtkWidget3ID(my->gtk_widget_get_type()); \
+ SetGtkFixed3ID(my->gtk_fixed_get_type()); \
SetGtkContainer3ID(my->gtk_container_get_type()); \
SetGtkBin3ID(my->gtk_bin_get_type()); \
SetGtkButton3ID(my->gtk_button_get_type()); \
+ SetGtkMenuButton3ID(my->gtk_menu_button_get_type()); \
SetGtkWindow3ID(my->gtk_window_get_type()); \
SetGtkApplicationWindowID(my->gtk_application_window_get_type());\
SetGtkListBoxID(my->gtk_list_box_get_type()); \
@@ -773,6 +808,7 @@ EXPORT void my3_gtk_clipboard_request_text(x64emu_t* emu, void* clipboard, void*
SetGtkGrid3ID(my->gtk_grid_get_type()); \
SetGtkMisc3ID(my->gtk_misc_get_type()); \
SetGtkLabel3ID(my->gtk_label_get_type()); \
+ SetGtkImage3ID(my->gtk_image_get_type()); \
SetGtkEventControllerID(my->gtk_event_controller_get_type());\
SetGtkGestureID(my->gtk_gesture_get_type()); \
SetGtkGestureSingleID(my->gtk_gesture_single_get_type()); \
diff --git a/src/wrapped/wrappedgtk3_private.h b/src/wrapped/wrappedgtk3_private.h
index a6e4e3e..c3ad3e6 100644
--- a/src/wrapped/wrappedgtk3_private.h
+++ b/src/wrapped/wrappedgtk3_private.h
@@ -15,7 +15,7 @@ GO(gtk_about_dialog_get_logo_icon_name, pFp)
GO(gtk_about_dialog_get_name, pFp)
GO(gtk_about_dialog_get_program_name, pFp)
GO(gtk_about_dialog_get_translator_credits, pFp)
-GO(gtk_about_dialog_get_type, pFv)
+GO(gtk_about_dialog_get_type, LFv)
GO(gtk_about_dialog_get_version, pFp)
GO(gtk_about_dialog_get_website, pFp)
GO(gtk_about_dialog_get_website_label, pFp)
@@ -45,7 +45,7 @@ GO(gtk_accelerator_name, pFui)
GO(gtk_accelerator_parse, vFppp)
GO(gtk_accelerator_set_default_mod_mask, vFu)
GO(gtk_accelerator_valid, iFuu)
-GO(gtk_accel_flags_get_type, pFv)
+GO(gtk_accel_flags_get_type, LFv)
GO(gtk_accel_group_activate, iFpupuu)
GO(gtk_accel_group_connect, vFpuiip) // Closure probably needs wrapping when not null
GO(gtk_accel_group_connect_by_path, vFppp)
@@ -55,7 +55,7 @@ GO(gtk_accel_group_disconnect_key, iFpuu)
GO(gtk_accel_group_from_accel_closure, pFp)
GO(gtk_accel_group_get_is_locked, iFp)
GO(gtk_accel_group_get_modifier_mask, uFp)
-GO(gtk_accel_group_get_type, pFv)
+GO(gtk_accel_group_get_type, LFv)
GO(gtk_accel_group_lock, vFp)
GO(gtk_accel_group_new, pFv)
GO(gtk_accel_group_query, pFpuup)
@@ -64,7 +64,7 @@ GO(gtk_accel_groups_from_object, pFp)
GO(gtk_accel_group_unlock, vFp)
GO(gtk_accel_label_get_accel_widget, pFp)
GO(gtk_accel_label_get_accel_width, uFp)
-GO(gtk_accel_label_get_type, pFv)
+GO(gtk_accel_label_get_type, LFv)
//GO(gtk_accel_label_new,
GO(gtk_accel_label_refetch, iFp)
//GO(gtk_accel_label_set_accel_closure,
@@ -75,7 +75,7 @@ GO(gtk_accel_map_change_entry, iFpuui)
//GO(gtk_accel_map_foreach,
//GO(gtk_accel_map_foreach_unfiltered,
GO(gtk_accel_map_get, pFv)
-GO(gtk_accel_map_get_type, pFv)
+GO(gtk_accel_map_get_type, LFv)
//GO(gtk_accel_map_load,
//GO(gtk_accel_map_load_fd,
//GO(gtk_accel_map_load_scanner,
@@ -85,12 +85,12 @@ GO(gtk_accel_map_lookup_entry, iFpp)
GO(gtk_accel_map_save_fd, vFi)
//GO(gtk_accel_map_unlock_path,
//GO(gtk_accessible_connect_widget_destroyed,
-GO(gtk_accessible_get_type, pFv)
+GO(gtk_accessible_get_type, LFv)
GO(gtk_accessible_get_widget, pFp)
GO(gtk_accessible_set_widget, vFpp)
-GO(gtk_actionable_get_type, pFv)
+GO(gtk_actionable_get_type, LFv)
//GO(gtk_action_activate,
-GO(gtk_action_bar_get_type, pFv)
+GO(gtk_action_bar_get_type, LFv)
//GO(gtk_action_block_activate,
//GO(gtk_action_block_activate_from,
//GO(gtk_action_connect_accelerator,
@@ -114,7 +114,7 @@ GO(gtk_action_get_proxies, pFp)
//GO(gtk_action_get_short_label,
//GO(gtk_action_get_stock_id,
//GO(gtk_action_get_tooltip,
-GO(gtk_action_get_type, pFv)
+GO(gtk_action_get_type, LFv)
//GO(gtk_action_get_visible,
//GO(gtk_action_get_visible_horizontal,
//GO(gtk_action_get_visible_vertical,
@@ -129,7 +129,7 @@ GO(gtk_action_group_add_action_with_accel, vFppp)
GO(gtk_action_group_get_action, pFpp)
GO(gtk_action_group_get_name, pFp)
//GO(gtk_action_group_get_sensitive,
-GO(gtk_action_group_get_type, pFv)
+GO(gtk_action_group_get_type, LFv)
GO(gtk_action_group_get_visible, iFp)
GO(gtk_action_group_list_actions, pFp)
GO(gtk_action_group_new, pFp)
@@ -160,7 +160,7 @@ GO(gtk_action_set_icon_name, vFpp)
//GO(gtk_action_unblock_activate_from,
GO(gtk_activatable_do_set_related_action, vFpp)
GO(gtk_activatable_get_related_action, pFp)
-GO(gtk_activatable_get_type, pFv)
+GO(gtk_activatable_get_type, LFv)
GO(gtk_activatable_get_use_action_appearance, iFp)
//GO(gtk_activatable_set_related_action,
GO(gtk_activatable_set_use_action_appearance, vFpi)
@@ -172,7 +172,7 @@ GO(gtk_adjustment_get_lower, dFp)
GO(gtk_adjustment_get_page_increment, dFp)
GO(gtk_adjustment_get_page_size, dFp)
GO(gtk_adjustment_get_step_increment, dFp)
-GO(gtk_adjustment_get_type, pFv)
+GO(gtk_adjustment_get_type, LFv)
GO(gtk_adjustment_get_upper, dFp)
GO(gtk_adjustment_get_value, dFp)
GO(gtk_adjustment_new, pFdddddd)
@@ -184,31 +184,31 @@ GO(gtk_adjustment_set_upper, vFpd)
GO(gtk_adjustment_set_value, vFpd)
GO(gtk_adjustment_value_changed, vFp)
GO(gtk_alignment_get_padding, vFppppp)
-GO(gtk_alignment_get_type, pFv)
+GO(gtk_alignment_get_type, LFv)
GO(gtk_alignment_new, pFffff)
GO(gtk_alignment_set, vFpffff)
GO(gtk_alignment_set_padding, vFpuuuu)
-GO(gtk_align_get_type, pFv)
+GO(gtk_align_get_type, LFv)
GO(gtk_alternative_dialog_button_order, iFp)
-GO(gtk_anchor_type_get_type, pFv)
+GO(gtk_anchor_type_get_type, LFv)
GO(gtk_application_add_window, vFpp)
GO(gtk_application_get_new, pFpi)
GO(gtk_application_get_type, LFv)
GO(gtk_application_new, pFpu)
GO(gtk_application_set_accels_for_action, vFppp)
GO(gtk_application_window_new, pFp)
-GO(gtk_application_window_get_type, pFv)
-GO(gtk_app_chooser_button_get_type, pFv)
-GO(gtk_app_chooser_dialog_get_type, pFv)
-GO(gtk_app_chooser_get_type, pFv)
-GO(gtk_app_chooser_widget_get_type, pFv)
-GO(gtk_arg_flags_get_type, pFv)
-GO(gtk_arrow_get_type, pFv)
+GO(gtk_application_window_get_type, LFv)
+GO(gtk_app_chooser_button_get_type, LFv)
+GO(gtk_app_chooser_dialog_get_type, LFv)
+GO(gtk_app_chooser_get_type, LFv)
+GO(gtk_app_chooser_widget_get_type, LFv)
+GO(gtk_arg_flags_get_type, LFv)
+GO(gtk_arrow_get_type, LFv)
GO(gtk_arrow_new, pFuu)
-GO(gtk_arrow_placement_get_type, pFv)
+GO(gtk_arrow_placement_get_type, LFv)
GO(gtk_arrow_set, vFpuu)
-GO(gtk_arrow_type_get_type, pFv)
-GO(gtk_aspect_frame_get_type, pFv)
+GO(gtk_arrow_type_get_type, LFv)
+GO(gtk_aspect_frame_get_type, LFv)
GO(gtk_aspect_frame_new, pFpfffi)
GO(gtk_aspect_frame_set, vFpfffi)
//GO(gtk_assistant_add_action_widget,
@@ -222,10 +222,10 @@ GO(gtk_assistant_get_nth_page, pFpi)
GO(gtk_assistant_get_page_side_image, pFpp)
GO(gtk_assistant_get_page_title, pFpp)
GO(gtk_assistant_get_page_type, uFpp)
-GO(gtk_assistant_get_type, pFv)
+GO(gtk_assistant_get_type, LFv)
GO(gtk_assistant_insert_page, iFppi)
//GO(gtk_assistant_new,
-GO(gtk_assistant_page_type_get_type, pFv)
+GO(gtk_assistant_page_type_get_type, LFv)
//GO(gtk_assistant_prepend_page,
GO(gtk_assistant_remove_action_widget, vFpp)
//GO(gtk_assistant_set_current_page,
@@ -236,7 +236,7 @@ GO(gtk_assistant_set_page_side_image, vFppp)
GO(gtk_assistant_set_page_title, vFppp)
GO(gtk_assistant_set_page_type, vFppu)
//GO(gtk_assistant_update_buttons_state,
-GO(gtk_attach_options_get_type, pFv)
+GO(gtk_attach_options_get_type, LFv)
//GO(gtk_binding_entry_add_signal,
GO(gtk_binding_entry_add_signall, vFpuupp)
//GO(gtk_binding_entry_clear,
@@ -251,14 +251,14 @@ GO(gtk_binding_set_by_class, pFp)
GO(gtk_binding_set_find, pFp)
//GO(gtk_binding_set_new,
GO(gtk_bin_get_child, pFp)
-GO(gtk_bin_get_type, pFv)
+GO(gtk_bin_get_type, LFv)
GO(gtk_border_copy, pFp)
GO(gtk_border_free, vFp)
-GO(gtk_border_get_type, pFv)
+GO(gtk_border_get_type, LFv)
GO(gtk_border_new, pFv)
GO(gtk_box_get_homogeneous, iFp)
GO(gtk_box_get_spacing, iFp)
-GO(gtk_box_get_type, pFv)
+GO(gtk_box_get_type, LFv)
GO(gtk_box_new, pFui)
GO(gtk_box_pack_end, vFppiiu)
GO(gtk_box_pack_end_defaults, vFpp)
@@ -276,7 +276,7 @@ GO(gtk_buildable_custom_tag_end, vFppppp)
GO(gtk_buildable_custom_tag_start, iFpppppp)
GO(gtk_buildable_get_internal_child, pFppp)
GO(gtk_buildable_get_name, pFp)
-GO(gtk_buildable_get_type, pFv)
+GO(gtk_buildable_get_type, LFv)
GO(gtk_buildable_parser_finished, vFpp)
GO(gtk_buildable_set_buildable_property, vFpppp)
GO(gtk_buildable_set_name, vFpp)
@@ -287,29 +287,29 @@ GO(gtk_builder_add_objects_from_file, uFpppp)
GO(gtk_builder_add_objects_from_string, uFppLpp)
GOM(gtk_builder_connect_signals, vFEpp)
GOM(gtk_builder_connect_signals_full, vFEppp)
-GO(gtk_builder_error_get_type, pFv)
+GO(gtk_builder_error_get_type, LFv)
GO(gtk_builder_error_quark, pFv)
GO(gtk_builder_get_object, pFpp)
GO(gtk_builder_get_objects, pFp)
GO(gtk_builder_get_translation_domain, pFp)
-GO(gtk_builder_get_type, pFv)
+GO(gtk_builder_get_type, LFv)
GO(gtk_builder_get_type_from_name, LFpp)
GO(gtk_builder_new, pFv)
GO(gtk_builder_set_translation_domain, vFpp)
GO(gtk_builder_value_from_string, iFppppp)
GO(gtk_builder_value_from_string_type, iFpLppp)
-GO(gtk_button_action_get_type, pFv)
+GO(gtk_button_action_get_type, LFv)
GO(gtk_button_box_get_child_ipadding, vFppp)
GO(gtk_button_box_get_child_secondary, iFpp)
GO(gtk_button_box_get_child_size, vFppp)
GO(gtk_button_box_get_layout, uFp)
-GO(gtk_button_box_get_type, pFv)
+GO(gtk_button_box_get_type, LFv)
GO(gtk_button_box_new, pFi)
GO(gtk_button_box_set_child_ipadding, vFpii)
GO(gtk_button_box_set_child_secondary, vFppi)
GO(gtk_button_box_set_child_size, vFpii)
GO(gtk_button_box_set_layout, vFpu)
-GO(gtk_button_box_style_get_type, pFv)
+GO(gtk_button_box_style_get_type, LFv)
//GO(gtk_button_clicked,
//GO(gtk_button_enter,
GO(gtk_button_get_alignment, vFppp)
@@ -319,7 +319,7 @@ GO(gtk_button_get_image, pFp)
GO(gtk_button_get_image_position, uFp)
GO(gtk_button_get_label, pFp)
GO(gtk_button_get_relief, uFp)
-GO(gtk_button_get_type, pFv)
+GO(gtk_button_get_type, LFv)
GO(gtk_button_get_use_stock, iFp)
GO(gtk_button_get_use_underline, iFp)
GO(gtk_button_leave, vFp)
@@ -330,6 +330,7 @@ GO(gtk_button_new_with_mnemonic, pFp)
GO(gtk_button_pressed, vFp)
GO(gtk_button_released, vFp)
GO(gtk_button_set_alignment, vFpff)
+GO(gtk_button_set_always_show_image, vFpi)
GO(gtk_button_set_focus_on_click, vFpi)
GO(gtk_button_set_image, vFpp)
GO(gtk_button_set_image_position, vFpu)
@@ -337,16 +338,17 @@ GO(gtk_button_set_label, vFpp)
GO(gtk_button_set_relief, vFpu)
GO(gtk_button_set_use_stock, vFpi)
GO(gtk_button_set_use_underline, vFpi)
-GO(gtk_buttons_type_get_type, pFv)
+GO(gtk_buttons_type_get_type, LFv)
+GO(gtk_cairo_should_draw_window, iFpp)
//GO(gtk_calendar_clear_marks,
//GO(gtk_calendar_display_options,
-GO(gtk_calendar_display_options_get_type, pFv)
+GO(gtk_calendar_display_options_get_type, LFv)
//GO(gtk_calendar_freeze,
GO(gtk_calendar_get_date, vFpppp)
GO(gtk_calendar_get_detail_height_rows, iFp)
//GO(gtk_calendar_get_detail_width_chars,
GO(gtk_calendar_get_display_options, uFp)
-GO(gtk_calendar_get_type, pFv)
+GO(gtk_calendar_get_type, LFv)
//GO(gtk_calendar_mark_day,
//GO(gtk_calendar_new,
//GO(gtk_calendar_select_day,
@@ -358,24 +360,24 @@ GO(gtk_calendar_set_display_options, vFpu)
//GO(gtk_calendar_thaw,
GO(gtk_calendar_unmark_day, vFpu)
//GO(gtk_cell_editable_editing_done,
-GO(gtk_cell_editable_get_type, pFv)
+GO(gtk_cell_editable_get_type, LFv)
//GO(gtk_cell_editable_remove_widget,
GO(gtk_cell_editable_start_editing, vFpp)
GO(gtk_cell_layout_add_attribute, vFpppi)
GO(gtk_cell_layout_clear, vFp)
GO(gtk_cell_layout_clear_attributes, vFpp)
GO(gtk_cell_layout_get_cells, pFp)
-GO(gtk_cell_layout_get_type, pFv)
+GO(gtk_cell_layout_get_type, LFv)
GO(gtk_cell_layout_pack_end, vFppi)
GO(gtk_cell_layout_pack_start, vFppi)
GO(gtk_cell_layout_reorder, vFppi)
GO(gtk_cell_layout_set_attributes, vFpppppppppp) // vaarg
//GOM(gtk_cell_layout_set_cell_data_func, vFEppppp)
-GO(gtk_cell_renderer_accel_get_type, pFv)
-GO(gtk_cell_renderer_accel_mode_get_type, pFv)
+GO(gtk_cell_renderer_accel_get_type, LFv)
+GO(gtk_cell_renderer_accel_mode_get_type, LFv)
//GO(gtk_cell_renderer_accel_new,
GO(gtk_cell_renderer_activate, iFppppppu)
-GO(gtk_cell_renderer_combo_get_type, pFv)
+GO(gtk_cell_renderer_combo_get_type, LFv)
//GO(gtk_cell_renderer_combo_new,
//GO(gtk_cell_renderer_editing_canceled,
GO(gtk_cell_renderer_get_alignment, vFppp)
@@ -383,12 +385,12 @@ GO(gtk_cell_renderer_get_alignment, vFppp)
GO(gtk_cell_renderer_get_padding, vFppp)
//GO(gtk_cell_renderer_get_sensitive,
GO(gtk_cell_renderer_get_size, vFppppppp)
-GO(gtk_cell_renderer_get_type, pFv)
+GO(gtk_cell_renderer_get_type, LFv)
//GO(gtk_cell_renderer_get_visible,
-GO(gtk_cell_renderer_mode_get_type, pFv)
-GO(gtk_cell_renderer_pixbuf_get_type, pFv)
+GO(gtk_cell_renderer_mode_get_type, LFv)
+GO(gtk_cell_renderer_pixbuf_get_type, LFv)
GO(gtk_cell_renderer_pixbuf_new, pFv)
-GO(gtk_cell_renderer_progress_get_type, pFv)
+GO(gtk_cell_renderer_progress_get_type, LFv)
//GO(gtk_cell_renderer_progress_new,
GO(gtk_cell_renderer_render, vFpppppu)
GO(gtk_cell_renderer_set_alignment, vFpff)
@@ -396,30 +398,30 @@ GO(gtk_cell_renderer_set_alignment, vFpff)
GO(gtk_cell_renderer_set_padding, vFpii)
//GO(gtk_cell_renderer_set_sensitive,
//GO(gtk_cell_renderer_set_visible,
-GO(gtk_cell_renderer_spin_get_type, pFv)
-GO(gtk_cell_renderer_spinner_get_type, pFv)
+GO(gtk_cell_renderer_spin_get_type, LFv)
+GO(gtk_cell_renderer_spinner_get_type, LFv)
//GO(gtk_cell_renderer_spinner_new,
//GO(gtk_cell_renderer_spin_new,
GO(gtk_cell_renderer_start_editing, pFppppppu)
-GO(gtk_cell_renderer_state_get_type, pFv)
+GO(gtk_cell_renderer_state_get_type, LFv)
GO(gtk_cell_renderer_stop_editing, vFpi)
-GO(gtk_cell_renderer_text_get_type, pFv)
+GO(gtk_cell_renderer_text_get_type, LFv)
GO(gtk_cell_renderer_text_new, pFv)
GO(gtk_cell_renderer_text_set_fixed_height_from_font, vFpi)
GO(gtk_cell_renderer_toggle_get_activatable, iFp)
GO(gtk_cell_renderer_toggle_get_active, iFp)
GO(gtk_cell_renderer_toggle_get_radio, iFp)
-GO(gtk_cell_renderer_toggle_get_type, pFv)
+GO(gtk_cell_renderer_toggle_get_type, LFv)
GO(gtk_cell_renderer_toggle_new, pFv)
GO(gtk_cell_renderer_toggle_set_activatable, vFpi)
GO(gtk_cell_renderer_toggle_set_active, vFpi)
GO(gtk_cell_renderer_toggle_set_radio, vFpi)
-GO(gtk_cell_type_get_type, pFv)
+GO(gtk_cell_type_get_type, LFv)
//GO(gtk_cell_view_get_cell_renderers,
GO(gtk_cell_view_get_displayed_row, pFp)
GO(gtk_cell_view_get_model, pFp)
GO(gtk_cell_view_get_size_of_row, iFppp)
-GO(gtk_cell_view_get_type, pFv)
+GO(gtk_cell_view_get_type, LFv)
//GO(gtk_cell_view_new,
//GO(gtk_cell_view_new_with_markup,
GO(gtk_cell_view_new_with_pixbuf, pFp)
@@ -427,14 +429,14 @@ GO(gtk_cell_view_new_with_pixbuf, pFp)
GO(gtk_cell_view_set_background_color, vFpp)
GO(gtk_cell_view_set_displayed_row, vFpp)
GO(gtk_cell_view_set_model, vFpp)
-GO(gtk_check_button_get_type, pFv)
+GO(gtk_check_button_get_type, LFv)
GO(gtk_check_button_new, pFv)
GO(gtk_check_button_new_with_label, pFp)
GO(gtk_check_button_new_with_mnemonic, pFp)
GO(gtk_check_menu_item_get_active, iFp)
GO(gtk_check_menu_item_get_draw_as_radio, iFp)
GO(gtk_check_menu_item_get_inconsistent, iFp)
-GO(gtk_check_menu_item_get_type, pFv)
+GO(gtk_check_menu_item_get_type, LFv)
GO(gtk_check_menu_item_new, pFv)
GO(gtk_check_menu_item_new_with_label, pFp)
GO(gtk_check_menu_item_new_with_mnemonic, pFp)
@@ -450,7 +452,7 @@ GO(gtk_clipboard_get_default, pFp)
GO(gtk_clipboard_get_display, pFp)
GO(gtk_clipboard_get_for_display, pFpp)
GO(gtk_clipboard_get_owner, pFp)
-GO(gtk_clipboard_get_type, pFv)
+GO(gtk_clipboard_get_type, LFv)
//GOM(gtk_clipboard_request_contents, vFEpppp)
//GOM(gtk_clipboard_request_image, vFEppp)
//GOM(gtk_clipboard_request_rich_text, vFEpppp)
@@ -483,7 +485,7 @@ GO(gtk_clist_column_titles_active, vFp)
GO(gtk_clist_column_titles_hide, vFp)
GO(gtk_clist_column_titles_passive, vFp)
GO(gtk_clist_column_titles_show, vFp)
-GO(gtk_clist_drag_pos_get_type, pFv)
+GO(gtk_clist_drag_pos_get_type, LFv)
GO(gtk_clist_find_row_from_data, iFpp)
GO(gtk_clist_freeze, vFp)
GO(gtk_clist_get_cell_style, pFpii)
@@ -498,7 +500,7 @@ GO(gtk_clist_get_row_style, pFpi)
GO(gtk_clist_get_selectable, iFpi)
GO(gtk_clist_get_selection_info, iFpiipp)
GO(gtk_clist_get_text, iFpiip)
-GO(gtk_clist_get_type, pFv)
+GO(gtk_clist_get_type, LFv)
GO(gtk_clist_get_vadjustment, pFp)
GO(gtk_clist_insert, iFpip)
GO(gtk_clist_moveto, vFpiiff)
@@ -552,18 +554,20 @@ GO(gtk_clist_unselect_row, vFpii)
GO(gtk_color_button_get_alpha, WFp)
GO(gtk_color_button_get_color, vFpp)
GO(gtk_color_button_get_title, pFp)
-GO(gtk_color_button_get_type, pFv)
+GO(gtk_color_button_get_type, LFv)
GO(gtk_color_button_get_use_alpha, iFp)
GO(gtk_color_button_new, pFv)
GO(gtk_color_button_new_with_color, pFp)
+GO(gtk_color_button_new_with_rgba, pFp)
GO(gtk_color_button_set_alpha, vFpW)
GO(gtk_color_button_set_color, vFpp)
+GO(gtk_color_button_set_rgba, vFpp)
GO(gtk_color_button_set_title, vFpp)
GO(gtk_color_button_set_use_alpha, vFpi)
-GO(gtk_color_chooser_dialog_get_type, pFv)
-GO(gtk_color_chooser_get_type, pFv)
+GO(gtk_color_chooser_dialog_get_type, LFv)
+GO(gtk_color_chooser_get_type, LFv)
GO(gtk_color_selection_dialog_get_color_selection, pFp)
-GO(gtk_color_selection_dialog_get_type, pFv)
+GO(gtk_color_selection_dialog_get_type, LFv)
GO(gtk_color_selection_dialog_new, pFp)
GO(gtk_color_selection_get_color, vFpp)
GO(gtk_color_selection_get_current_alpha, WFp)
@@ -572,7 +576,7 @@ GO(gtk_color_selection_get_has_opacity_control, iFp)
GO(gtk_color_selection_get_has_palette, iFp)
GO(gtk_color_selection_get_previous_alpha, WFp)
GO(gtk_color_selection_get_previous_color, vFpp)
-GO(gtk_color_selection_get_type, pFv)
+GO(gtk_color_selection_get_type, LFv)
GO(gtk_color_selection_is_adjusting, iFp)
GO(gtk_color_selection_new, pFv)
GO(gtk_color_selection_palette_from_string, iFppp)
@@ -589,7 +593,7 @@ GO(gtk_color_selection_set_previous_color, vFpp)
GO(gtk_color_selection_set_update_policy, vFpi)
GO(gtk_combo_box_append_text, vFpp)
GO(gtk_combo_box_entry_get_text_column, iFp)
-GO(gtk_combo_box_entry_get_type, pFv)
+GO(gtk_combo_box_entry_get_type, LFv)
GO(gtk_combo_box_entry_new, pFv)
GO(gtk_combo_box_entry_new_text, pFv)
GO(gtk_combo_box_entry_new_with_model, pFpi)
@@ -608,7 +612,7 @@ GO(gtk_combo_box_get_popup_accessible, pFp)
//GOM(gtk_combo_box_get_row_separator_func, pFEp)
GO(gtk_combo_box_get_row_span_column, iFp)
GO(gtk_combo_box_get_title, pFp)
-GO(gtk_combo_box_get_type, pFv)
+GO(gtk_combo_box_get_type, LFv)
GO(gtk_combo_box_get_wrap_width, iFp)
GO(gtk_combo_box_insert_text, vFpip)
GO(gtk_combo_box_new, pFv)
@@ -635,7 +639,7 @@ GO(gtk_combo_box_set_wrap_width, vFpi)
GO(gtk_combo_box_text_append, vFppp)
GO(gtk_combo_box_text_append_text, vFpp)
GO(gtk_combo_box_text_get_active_text, pFp)
-GO(gtk_combo_box_text_get_type, pFv)
+GO(gtk_combo_box_text_get_type, LFv)
GO(gtk_combo_box_text_insert_text, vFpip)
GO(gtk_combo_box_text_new, pFv)
GO(gtk_combo_box_text_new_with_entry, pFv)
@@ -643,7 +647,7 @@ GO(gtk_combo_box_text_prepend_text, vFpp)
GO(gtk_combo_box_text_remove, vFpi)
GO(gtk_combo_box_text_remove_all, vFp)
GO(gtk_combo_disable_activate, vFp)
-GO(gtk_combo_get_type, pFv)
+GO(gtk_combo_get_type, LFv)
GO(gtk_combo_new, pFv)
GO(gtk_combo_set_case_sensitive, vFpi)
GO(gtk_combo_set_item_string, vFppp)
@@ -675,7 +679,7 @@ GO(gtk_container_get_focus_child, pFp)
GO(gtk_container_get_focus_hadjustment, pFp)
GO(gtk_container_get_focus_vadjustment, pFp)
GO(gtk_container_get_resize_mode, uFp)
-GO(gtk_container_get_type, pFv)
+GO(gtk_container_get_type, LFv)
GO(gtk_container_propagate_expose, vFppp)
GO(gtk_container_remove, vFpp)
GO(gtk_container_resize_children, vFp)
@@ -687,9 +691,10 @@ GO(gtk_container_set_focus_vadjustment, vFpp)
GO(gtk_container_set_reallocate_redraws, vFpi)
GO(gtk_container_set_resize_mode, vFpu)
GO(gtk_container_unset_focus_chain, vFp)
-GO(gtk_corner_type_get_type, pFv)
+GO(gtk_corner_type_get_type, LFv)
GO(gtk_css_provider_get_default, pFv)
GO(gtk_css_provider_get_named, pFpp)
+GO(gtk_css_provider_get_type, LFv)
GO(gtk_css_provider_load_from_data, iFpplp)
GO(gtk_css_provider_load_from_file, iFppp)
GO(gtk_css_provider_load_from_path, iFppp)
@@ -709,10 +714,10 @@ GO(gtk_css_section_unref, vFp)
//GO(gtk_ctree_collapse_recursive,
//GO(gtk_ctree_collapse_to_depth,
//GO(gtk_ctree_expand,
-GO(gtk_ctree_expander_style_get_type, pFv)
+GO(gtk_ctree_expander_style_get_type, LFv)
//GO(gtk_ctree_expand_recursive,
//GO(gtk_ctree_expand_to_depth,
-GO(gtk_ctree_expansion_type_get_type, pFv)
+GO(gtk_ctree_expansion_type_get_type, LFv)
//GO(gtk_ctree_export_to_gnode,
//GO(gtk_ctree_find,
//GO(gtk_ctree_find_all_by_row_data,
@@ -721,14 +726,14 @@ GO(gtk_ctree_expansion_type_get_type, pFv)
//GO(gtk_ctree_find_by_row_data_custom,
//GO(gtk_ctree_find_node_ptr,
//GO(gtk_ctree_get_node_info,
-GO(gtk_ctree_get_type, pFv)
+GO(gtk_ctree_get_type, LFv)
//GO(gtk_ctree_insert_gnode,
//GO(gtk_ctree_insert_node,
//GO(gtk_ctree_is_ancestor,
//GO(gtk_ctree_is_hot_spot,
//GO(gtk_ctree_is_viewable,
//GO(gtk_ctree_last,
-GO(gtk_ctree_line_style_get_type, pFv)
+GO(gtk_ctree_line_style_get_type, LFv)
//GO(gtk_ctree_move,
//GO(gtk_ctree_new,
//GO(gtk_ctree_new_with_titles,
@@ -740,7 +745,7 @@ GO(gtk_ctree_line_style_get_type, pFv)
//GO(gtk_ctree_node_get_row_style,
//GO(gtk_ctree_node_get_selectable,
//GO(gtk_ctree_node_get_text,
-GO(gtk_ctree_node_get_type, pFv)
+GO(gtk_ctree_node_get_type, LFv)
//GO(gtk_ctree_node_is_visible,
//GO(gtk_ctree_node_moveto,
//GO(gtk_ctree_node_nth,
@@ -755,7 +760,7 @@ GO(gtk_ctree_node_get_type, pFv)
//GO(gtk_ctree_node_set_selectable,
//GO(gtk_ctree_node_set_shift,
//GO(gtk_ctree_node_set_text,
-GO(gtk_ctree_pos_get_type, pFv)
+GO(gtk_ctree_pos_get_type, LFv)
//GO(gtk_ctree_post_recursive,
//GO(gtk_ctree_post_recursive_to_depth,
//GO(gtk_ctree_pre_recursive,
@@ -777,7 +782,7 @@ GO(gtk_ctree_pos_get_type, pFv)
//GO(gtk_ctree_toggle_expansion_recursive,
//GO(gtk_ctree_unselect,
//GO(gtk_ctree_unselect_recursive,
-GO(gtk_curve_get_type, pFv)
+GO(gtk_curve_get_type, LFv)
GO(gtk_curve_get_vector, vFpip)
GO(gtk_curve_new, pFv)
GO(gtk_curve_reset, vFp)
@@ -785,24 +790,24 @@ GO(gtk_curve_set_curve_type, vFpi)
GO(gtk_curve_set_gamma, vFpf)
GO(gtk_curve_set_range, vFpffff)
GO(gtk_curve_set_vector, vFpip)
-GO(gtk_curve_type_get_type, pFv)
-GO(gtk_custom_paper_unix_dialog_get_type, pFv)
-GO(gtk_debug_flag_get_type, pFv)
+GO(gtk_curve_type_get_type, LFv)
+GO(gtk_custom_paper_unix_dialog_get_type, LFv)
+GO(gtk_debug_flag_get_type, LFv)
GO(gtk_decorated_window_calculate_frame_size, vFp)
GO(gtk_decorated_window_init, vFp)
GO(gtk_decorated_window_move_resize_window, vFpiiii)
GO(gtk_decorated_window_set_title, vFpp)
-GO(gtk_delete_type_get_type, pFv)
-GO(gtk_dest_defaults_get_type, pFv)
+GO(gtk_delete_type_get_type, LFv)
+GO(gtk_dest_defaults_get_type, LFv)
GO(gtk_dialog_add_action_widget, vFppi)
GO(gtk_dialog_add_button, pFppi)
GOM(gtk_dialog_add_buttons, vFEppV)
-GO(gtk_dialog_flags_get_type, pFv)
+GO(gtk_dialog_flags_get_type, LFv)
GO(gtk_dialog_get_action_area, pFp)
GO(gtk_dialog_get_content_area, pFp)
GO(gtk_dialog_get_has_separator, iFp)
GO(gtk_dialog_get_response_for_widget, iFpp)
-GO(gtk_dialog_get_type, pFv)
+GO(gtk_dialog_get_type, LFv)
GO(gtk_dialog_get_widget_for_response, pFpi)
GO(gtk_dialog_new, pFv)
GO(gtk_dialog_new_with_buttons, pFppipppppppppppp) //vaarg
@@ -813,7 +818,7 @@ GO(gtk_dialog_set_alternative_button_order_from_array, vFpip)
GO(gtk_dialog_set_default_response, vFpi)
GO(gtk_dialog_set_has_separator, vFpi)
GO(gtk_dialog_set_response_sensitive, vFpii)
-GO(gtk_direction_type_get_type, pFv)
+GO(gtk_direction_type_get_type, LFv)
GO(gtk_disable_setlocale, vFv)
GO(gtk_distribute_natural_allocation, iFiup)
GO(gtk_drag_begin, pFppuip)
@@ -833,7 +838,7 @@ GO(gtk_drag_finish, vFpiiu)
GO(gtk_drag_get_data, vFpppu)
GO(gtk_drag_get_source_widget, pFp)
GO(gtk_drag_highlight, vFp)
-GO(gtk_drag_result_get_type, pFv)
+GO(gtk_drag_result_get_type, LFv)
GO(gtk_drag_set_default_icon, vFpppii)
GO(gtk_drag_set_icon_default, vFp)
GO(gtk_drag_set_icon_name, vFppii)
@@ -864,7 +869,7 @@ GO(gtk_draw_flat_box, vFppiiiiii)
GO(gtk_draw_focus, vFppiiii)
GO(gtk_draw_handle, vFppiiiiiii)
GO(gtk_draw_hline, vFppiiii)
-GO(gtk_drawing_area_get_type, pFv)
+GO(gtk_drawing_area_get_type, LFv)
GO(gtk_drawing_area_new, pFv)
GO(gtk_drawing_area_size, vFpii)
GO(gtk_draw_insertion_cursor, vFpppiui)
@@ -886,7 +891,7 @@ GO(gtk_editable_get_chars, pFpii)
GO(gtk_editable_get_editable, iFp)
GO(gtk_editable_get_position, iFp)
GO(gtk_editable_get_selection_bounds, iFppp)
-GO(gtk_editable_get_type, pFv)
+GO(gtk_editable_get_type, LFv)
GO(gtk_editable_insert_text, vFppip)
GO(gtk_editable_paste_clipboard, vFp)
GO(gtk_editable_select_region, vFpii)
@@ -900,7 +905,7 @@ GO(gtk_entry_buffer_get_bytes, LFp)
GO(gtk_entry_buffer_get_length, uFp)
GO(gtk_entry_buffer_get_max_length, iFp)
GO(gtk_entry_buffer_get_text, pFp)
-GO(gtk_entry_buffer_get_type, pFv)
+GO(gtk_entry_buffer_get_type, LFv)
GO(gtk_entry_buffer_insert_text, uFpupi)
GO(gtk_entry_buffer_new, pFpi)
GO(gtk_entry_buffer_set_max_length, vFpi)
@@ -917,7 +922,7 @@ GO(gtk_entry_completion_get_model, pFp)
//GO(gtk_entry_completion_get_popup_set_width,
GO(gtk_entry_completion_get_popup_single_match, iFp)
GO(gtk_entry_completion_get_text_column, iFp)
-GO(gtk_entry_completion_get_type, pFv)
+GO(gtk_entry_completion_get_type, LFv)
GO(gtk_entry_completion_insert_action_markup, vFpip)
//GO(gtk_entry_completion_insert_action_text,
//GO(gtk_entry_completion_insert_prefix,
@@ -960,10 +965,10 @@ GO(gtk_entry_get_progress_pulse_step, dFp)
GO(gtk_entry_get_text, pFp)
GO(gtk_entry_get_text_length, WFp)
//GO(gtk_entry_get_text_window,
-GO(gtk_entry_get_type, pFv)
+GO(gtk_entry_get_type, LFv)
//GO(gtk_entry_get_visibility,
GO(gtk_entry_get_width_chars, iFp)
-GO(gtk_entry_icon_position_get_type, pFv)
+GO(gtk_entry_icon_position_get_type, LFv)
GO(gtk_entry_im_context_filter_keypress, iFpp)
//GO(gtk_entry_layout_index_to_text_index,
GO(gtk_entry_new, pFv)
@@ -1003,11 +1008,12 @@ GO(gtk_entry_text_index_to_layout_index, iFpi)
//GO(gtk_entry_unset_invisible_char,
GOM(gtk_enumerate_printers, vFEpppi)
GO(gtk_event_box_get_above_child, iFp)
-GO(gtk_event_box_get_type, pFv)
+GO(gtk_event_box_get_type, LFv)
GO(gtk_event_box_get_visible_window, iFp)
GO(gtk_event_box_new, pFv)
GO(gtk_event_box_set_above_child, vFpi)
GO(gtk_event_box_set_visible_window, vFpi)
+GO(gtk_event_controller_set_propagation_phase, vFpi)
GO(gtk_events_pending, iFv)
GO(gtk_exit, vFi)
GO(gtk_expander_get_expanded, iFp)
@@ -1015,7 +1021,7 @@ GO(gtk_expander_get_label, pFp)
GO(gtk_expander_get_label_fill, iFp)
GO(gtk_expander_get_label_widget, pFp)
GO(gtk_expander_get_spacing, iFp)
-GO(gtk_expander_get_type, pFv)
+GO(gtk_expander_get_type, LFv)
GO(gtk_expander_get_use_markup, iFp)
GO(gtk_expander_get_use_underline, iFp)
GO(gtk_expander_new, pFp)
@@ -1027,15 +1033,15 @@ GO(gtk_expander_set_label_widget, vFpp)
GO(gtk_expander_set_spacing, vFpi)
GO(gtk_expander_set_use_markup, vFpi)
GO(gtk_expander_set_use_underline, vFpi)
-GO(gtk_expander_style_get_type, pFv)
+GO(gtk_expander_style_get_type, LFv)
GO(gtk_false, iFv)
-GO(gtk_file_chooser_action_get_type, pFv)
+GO(gtk_file_chooser_action_get_type, LFv)
GO(gtk_file_chooser_add_filter, vFpp)
GO(gtk_file_chooser_add_shortcut_folder, iFppp)
GO(gtk_file_chooser_add_shortcut_folder_uri, iFppp)
GO(gtk_file_chooser_button_get_focus_on_click, iFp)
GO(gtk_file_chooser_button_get_title, pFp)
-GO(gtk_file_chooser_button_get_type, pFv)
+GO(gtk_file_chooser_button_get_type, LFv)
GO(gtk_file_chooser_button_get_width_chars, iFp)
GO(gtk_file_chooser_button_new, pFpu)
GO(gtk_file_chooser_button_new_with_backend, pFpip)
@@ -1043,11 +1049,11 @@ GO(gtk_file_chooser_button_new_with_dialog, pFp)
GO(gtk_file_chooser_button_set_focus_on_click, vFpi)
GO(gtk_file_chooser_button_set_title, vFpp)
GO(gtk_file_chooser_button_set_width_chars, vFpi)
-GO(gtk_file_chooser_confirmation_get_type, pFv)
-GO(gtk_file_chooser_dialog_get_type, pFv)
+GO(gtk_file_chooser_confirmation_get_type, LFv)
+GO(gtk_file_chooser_dialog_get_type, LFv)
GO(gtk_file_chooser_dialog_new, pFppipipipipipipip) // vaargs (so pFppipV) with additionnal buttons, end with a NULL
GO(gtk_file_chooser_dialog_new_with_backend, pFppippipipipipipip) // same but pFppippV
-GO(gtk_file_chooser_error_get_type, pFv)
+GO(gtk_file_chooser_error_get_type, LFv)
GO(gtk_file_chooser_error_quark, pFv)
GO(gtk_file_chooser_get_action, uFp)
GO(gtk_file_chooser_get_create_folders, iFp)
@@ -1070,13 +1076,14 @@ GO(gtk_file_chooser_get_preview_widget, pFp)
GO(gtk_file_chooser_get_preview_widget_active, iFp)
GO(gtk_file_chooser_get_select_multiple, iFp)
GO(gtk_file_chooser_get_show_hidden, iFp)
-GO(gtk_file_chooser_get_type, pFv)
+GO(gtk_file_chooser_get_type, LFv)
GO(gtk_file_chooser_get_uri, pFp)
GO(gtk_file_chooser_get_uris, pFp)
GO(gtk_file_chooser_get_use_preview_label, iFp)
GO(gtk_file_chooser_list_filters, pFp)
GO(gtk_file_chooser_list_shortcut_folders, pFp)
GO(gtk_file_chooser_list_shortcut_folder_uris, pFp)
+GO(gtk_file_chooser_native_new, pFppipp)
GO(gtk_file_chooser_remove_filter, vFpp)
GO(gtk_file_chooser_remove_shortcut_folder, iFppp)
GO(gtk_file_chooser_remove_shortcut_folder_uri, iFppp)
@@ -1106,7 +1113,7 @@ GO(gtk_file_chooser_unselect_all, vFp)
GO(gtk_file_chooser_unselect_file, vFpp)
GO(gtk_file_chooser_unselect_filename, vFpp)
GO(gtk_file_chooser_unselect_uri, vFpp)
-GO(gtk_file_chooser_widget_get_type, pFv)
+GO(gtk_file_chooser_widget_get_type, LFv)
GO(gtk_file_chooser_widget_new, pFu)
GO(gtk_file_chooser_widget_new_with_backend, pFip)
//GOM(gtk_file_filter_add_custom, vFEppppp)
@@ -1114,35 +1121,35 @@ GO(gtk_file_filter_add_mime_type, vFpp)
GO(gtk_file_filter_add_pattern, vFpp)
GO(gtk_file_filter_add_pixbuf_formats, vFp)
GO(gtk_file_filter_filter, iFpp)
-GO(gtk_file_filter_flags_get_type, pFv)
+GO(gtk_file_filter_flags_get_type, LFv)
GO(gtk_file_filter_get_name, pFp)
GO(gtk_file_filter_get_needed, uFp)
-GO(gtk_file_filter_get_type, pFv)
+GO(gtk_file_filter_get_type, LFv)
GO(gtk_file_filter_new, pFv)
GO(gtk_file_filter_set_name, vFpp)
GO(gtk_file_selection_complete, vFpp)
GO(gtk_file_selection_get_filename, pFp)
GO(gtk_file_selection_get_selections, pFp)
GO(gtk_file_selection_get_select_multiple, iFp)
-GO(gtk_file_selection_get_type, pFv)
+GO(gtk_file_selection_get_type, LFv)
GO(gtk_file_selection_hide_fileop_buttons, vFp)
GO(gtk_file_selection_new, pFp)
GO(gtk_file_selection_set_filename, vFpp)
GO(gtk_file_selection_set_select_multiple, vFpi)
GO(gtk_file_selection_show_fileop_buttons, vFp)
GO(gtk_fixed_get_has_window, iFp)
-GO(gtk_fixed_get_type, pFv)
+GO(gtk_fixed_get_type, LFv)
GO(gtk_fixed_move, vFppii)
GO(gtk_fixed_new, pFv)
GO(gtk_fixed_put, vFppii)
GO(gtk_fixed_set_has_window, vFpi)
-GO(gtk_flow_box_child_get_type, pFv)
-GO(gtk_flow_box_get_type, pFv)
+GO(gtk_flow_box_child_get_type, LFv)
+GO(gtk_flow_box_get_type, LFv)
GO(gtk_font_button_get_font_name, pFp)
GO(gtk_font_button_get_show_size, iFp)
GO(gtk_font_button_get_show_style, iFp)
GO(gtk_font_button_get_title, pFp)
-GO(gtk_font_button_get_type, pFv)
+GO(gtk_font_button_get_type, LFv)
GO(gtk_font_button_get_use_font, iFp)
GO(gtk_font_button_get_use_size, iFp)
GO(gtk_font_button_new, pFv)
@@ -1153,7 +1160,7 @@ GO(gtk_font_button_set_show_style, vFpi)
GO(gtk_font_button_set_title, vFpp)
GO(gtk_font_button_set_use_font, vFpi)
GO(gtk_font_button_set_use_size, vFpi)
-GO(gtk_font_chooser_get_type, pFv)
+GO(gtk_font_chooser_get_type, LFv)
GO(gtk_font_selection_dialog_get_apply_button, pFp)
GO(gtk_font_selection_dialog_get_cancel_button, pFp)
GO(gtk_font_selection_dialog_get_font, pFp)
@@ -1161,7 +1168,7 @@ GO(gtk_font_selection_dialog_get_font_name, pFp)
GO(gtk_font_selection_dialog_get_font_selection, pFp)
GO(gtk_font_selection_dialog_get_ok_button, pFp)
GO(gtk_font_selection_dialog_get_preview_text, pFp)
-GO(gtk_font_selection_dialog_get_type, pFv)
+GO(gtk_font_selection_dialog_get_type, LFv)
GO(gtk_font_selection_dialog_new, pFp)
GO(gtk_font_selection_dialog_set_font_name, iFpp)
GO(gtk_font_selection_dialog_set_preview_text, vFpp)
@@ -1176,7 +1183,7 @@ GO(gtk_font_selection_get_preview_text, pFp)
GO(gtk_font_selection_get_size, iFp)
GO(gtk_font_selection_get_size_entry, pFp)
GO(gtk_font_selection_get_size_list, pFp)
-GO(gtk_font_selection_get_type, pFv)
+GO(gtk_font_selection_get_type, LFv)
GO(gtk_font_selection_new, pFv)
GO(gtk_font_selection_set_font_name, iFpp)
GO(gtk_font_selection_set_preview_text, vFpp)
@@ -1184,17 +1191,19 @@ GO(gtk_frame_get_label, pFp)
GO(gtk_frame_get_label_align, vFppp)
GO(gtk_frame_get_label_widget, pFp)
GO(gtk_frame_get_shadow_type, uFp)
-GO(gtk_frame_get_type, pFv)
+GO(gtk_frame_get_type, LFv)
GO(gtk_frame_new, pFp)
GO(gtk_frame_set_label, vFpp)
GO(gtk_frame_set_label_align, vFpff)
GO(gtk_frame_set_label_widget, vFpp)
GO(gtk_frame_set_shadow_type, vFpu)
-GO(gtk_gamma_curve_get_type, pFv)
+GO(gtk_gamma_curve_get_type, LFv)
GO(gtk_gamma_curve_new, pFv)
GO(gtk_gc_get, pFippu)
GO(gtk_gc_release, vFp)
+GO(gtk_gesture_is_active, iFp)
GO(gtk_gesture_long_press_new, pFv)
+GO(gtk_gesture_pan_new, pFpi)
GO(gtk_get_current_event, pFv)
GO(gtk_get_current_event_state, iFp)
GO(gtk_get_current_event_time, uFv)
@@ -1210,7 +1219,8 @@ GO(gtk_grab_add, vFp)
GO(gtk_grab_get_current, pFv)
GO(gtk_grab_remove, vFp)
GO(gtk_grid_attach, vFppiiii)
-GO(gtk_grid_get_type, pFv)
+GO(gtk_grid_get_type, LFv)
+GO(gtk_grid_new, pFv)
GO(gtk_grid_set_column_homogeneous, vFpi)
GO(gtk_grid_set_column_spacing, vFpu)
GO(gtk_grid_set_row_homogeneous, vFpi)
@@ -1219,16 +1229,16 @@ GO(gtk_handle_box_get_child_detached, iFp)
GO(gtk_handle_box_get_handle_position, iFp)
GO(gtk_handle_box_get_shadow_type, uFp)
GO(gtk_handle_box_get_snap_edge, uFp)
-GO(gtk_handle_box_get_type, pFv)
+GO(gtk_handle_box_get_type, LFv)
GO(gtk_handle_box_new, pFv)
GO(gtk_handle_box_set_handle_position, vFpi)
GO(gtk_handle_box_set_shadow_type, vFpu)
GO(gtk_handle_box_set_snap_edge, vFpu)
-GO(gtk_hbox_get_type, pFv)
+GO(gtk_hbox_get_type, LFv)
GO(gtk_hbox_new, pFii)
GO(gtk_hbutton_box_get_layout_default, iFv)
GO(gtk_hbutton_box_get_spacing_default, iFv)
-GO(gtk_hbutton_box_get_type, pFv)
+GO(gtk_hbutton_box_get_type, LFv)
GO(gtk_hbutton_box_new, pFv)
GO(gtk_hbutton_box_set_layout_default, vFi)
GO(gtk_hbutton_box_set_spacing_default, vFi)
@@ -1237,20 +1247,20 @@ GO(gtk_header_bar_get_type, lFv)
GO(gtk_header_bar_pack_end, vFpp)
GO(gtk_header_bar_set_show_close_button, vFpi)
GO(gtk_header_bar_set_title, vFpp)
-GO(gtk_hpaned_get_type, pFv)
+GO(gtk_hpaned_get_type, LFv)
//GO(gtk_hpaned_new,
-GO(gtk_hruler_get_type, pFv)
+GO(gtk_hruler_get_type, LFv)
//GO(gtk_hruler_new,
-GO(gtk_hscale_get_type, pFv)
+GO(gtk_hscale_get_type, LFv)
GO(gtk_hscale_new, pFp)
GO(gtk_hscale_new_with_range, pFddd)
-GO(gtk_hscrollbar_get_type, pFv)
+GO(gtk_hscrollbar_get_type, LFv)
GO(gtk_hscrollbar_new, pFp)
-GO(gtk_hseparator_get_type, pFv)
+GO(gtk_hseparator_get_type, LFv)
GO(gtk_hseparator_new, pFv)
GO(gtk_hsv_get_color, vFpppp)
GO(gtk_hsv_get_metrics, vFppp)
-GO(gtk_hsv_get_type, pFv)
+GO(gtk_hsv_get_type, LFv)
GO(gtk_hsv_is_adjusting, iFp)
//GO(gtk_hsv_new,
GO(gtk_hsv_set_color, vFpddd)
@@ -1258,7 +1268,7 @@ GO(gtk_hsv_set_metrics, vFpii)
//GO(gtk_hsv_to_rgb,
GO(gtk_icon_factory_add, vFppp)
GO(gtk_icon_factory_add_default, vFp)
-GO(gtk_icon_factory_get_type, pFv)
+GO(gtk_icon_factory_get_type, LFv)
GO(gtk_icon_factory_lookup, pFpp)
GO(gtk_icon_factory_lookup_default, pFp)
GO(gtk_icon_factory_new, pFv)
@@ -1271,17 +1281,17 @@ GO(gtk_icon_info_get_builtin_pixbuf, pFp)
GO(gtk_icon_info_get_display_name, pFp)
GO(gtk_icon_info_get_embedded_rect, iFpp)
GO(gtk_icon_info_get_filename, pFp)
-GO(gtk_icon_info_get_type, pFv)
+GO(gtk_icon_info_get_type, LFv)
GO(gtk_icon_info_load_icon, pFpp)
GO(gtk_icon_info_load_surface, pFppp)
GO(gtk_icon_info_load_symbolic_for_context, pFpppp)
GO(gtk_icon_info_new_for_pixbuf, pFpp)
GO(gtk_icon_info_set_raw_coordinates, vFpi)
-GO(gtk_icon_lookup_flags_get_type, pFv)
+GO(gtk_icon_lookup_flags_get_type, LFv)
GO(gtk_icon_set_add_source, vFpp)
GO(gtk_icon_set_copy, pFp)
GO(gtk_icon_set_get_sizes, vFppp)
-GO(gtk_icon_set_get_type, pFv)
+GO(gtk_icon_set_get_type, LFv)
GO(gtk_icon_set_new, pFv)
GO(gtk_icon_set_new_from_pixbuf, pFp)
GO(gtk_icon_set_ref, pFp)
@@ -1289,7 +1299,7 @@ GO(gtk_icon_set_render_icon, pFppuuupp)
GO(gtk_icon_set_unref, vFp)
GO(gtk_icon_size_from_name, uFp)
GO(gtk_icon_size_get_name, pFu)
-GO(gtk_icon_size_get_type, pFv)
+GO(gtk_icon_size_get_type, LFv)
GO(gtk_icon_size_lookup, iFupp)
GO(gtk_icon_size_lookup_for_settings, iFpupp)
GO(gtk_icon_size_register, uFpii)
@@ -1305,7 +1315,7 @@ GO(gtk_icon_source_get_size, uFp)
GO(gtk_icon_source_get_size_wildcarded, iFp)
GO(gtk_icon_source_get_state, uFp)
GO(gtk_icon_source_get_state_wildcarded, iFp)
-GO(gtk_icon_source_get_type, pFv)
+GO(gtk_icon_source_get_type, LFv)
GO(gtk_icon_source_new, pFv)
GO(gtk_icon_source_set_direction, vFpu)
GO(gtk_icon_source_set_direction_wildcarded, vFpi)
@@ -1319,7 +1329,7 @@ GO(gtk_icon_source_set_state_wildcarded, vFpi)
GO(gtk_icon_theme_add_builtin_icon, vFpip)
GO(gtk_icon_theme_append_search_path, vFpp)
GO(gtk_icon_theme_choose_icon, pFppiu)
-GO(gtk_icon_theme_error_get_type, pFv)
+GO(gtk_icon_theme_error_get_type, LFv)
//GO(gtk_icon_theme_error_quark,
GO(gtk_icon_theme_get_default, pFv)
GO(gtk_icon_theme_get_example_icon_name, pFp)
@@ -1327,7 +1337,7 @@ GO(gtk_icon_theme_get_for_display, pFp)
GO(gtk_icon_theme_get_for_screen, pFp)
GO(gtk_icon_theme_get_icon_sizes, pFpp)
GO(gtk_icon_theme_get_search_path, vFppp)
-GO(gtk_icon_theme_get_type, pFv)
+GO(gtk_icon_theme_get_type, LFv)
GO(gtk_icon_theme_has_icon, iFpp)
GO(gtk_icon_theme_list_contexts, pFp)
GO(gtk_icon_theme_list_icons, pFpp)
@@ -1343,7 +1353,7 @@ GO(gtk_icon_theme_set_screen, vFpp)
GO(gtk_icon_theme_set_search_path, vFppi)
GO(gtk_icon_view_convert_widget_to_bin_window_coords, vFpiipp)
GO(gtk_icon_view_create_drag_icon, pFpp)
-GO(gtk_icon_view_drop_position_get_type, pFv)
+GO(gtk_icon_view_drop_position_get_type, LFv)
GO(gtk_icon_view_enable_model_drag_dest, vFppiu)
GO(gtk_icon_view_enable_model_drag_source, vFpupiu)
GO(gtk_icon_view_get_columns, iFp)
@@ -1371,7 +1381,7 @@ GO(gtk_icon_view_get_spacing, iFp)
GO(gtk_icon_view_get_text_column, iFp)
GO(gtk_icon_view_get_tooltip_column, iFp)
GO(gtk_icon_view_get_tooltip_context, iFpppippp)
-GO(gtk_icon_view_get_type, pFv)
+GO(gtk_icon_view_get_type, LFv)
GO(gtk_icon_view_get_visible_range, iFppp)
GO(gtk_icon_view_item_activated, vFpp)
GO(gtk_icon_view_new, pFv)
@@ -1405,7 +1415,7 @@ GO(gtk_icon_view_unselect_all, vFp)
GO(gtk_icon_view_unselect_path, vFpp)
GO(gtk_icon_view_unset_model_drag_dest, vFp)
GO(gtk_icon_view_unset_model_drag_source, vFp)
-GO(gtk_identifier_get_type, pFv)
+GO(gtk_identifier_get_type, LFv)
//GOM(gtk_idle_add, uFEBp)
//GOM(gtk_idle_add_full, uFEiBppB)
//GOM(gtk_idle_add_priority, uFEiBp)
@@ -1423,10 +1433,10 @@ GO(gtk_image_get_pixel_size, iFp)
GO(gtk_image_get_pixmap, vFppp)
GO(gtk_image_get_stock, vFppp)
GO(gtk_image_get_storage_type, uFp)
-GO(gtk_image_get_type, pFv)
+GO(gtk_image_get_type, LFv)
GO(gtk_image_menu_item_get_always_show_image, iFp)
GO(gtk_image_menu_item_get_image, pFp)
-GO(gtk_image_menu_item_get_type, pFv)
+GO(gtk_image_menu_item_get_type, LFv)
GO(gtk_image_menu_item_get_use_stock, iFp)
GO(gtk_image_menu_item_new, pFv)
GO(gtk_image_menu_item_new_from_stock, pFpp)
@@ -1457,7 +1467,7 @@ GO(gtk_image_set_from_pixbuf, vFpp)
GO(gtk_image_set_from_pixmap, vFppp)
GO(gtk_image_set_from_stock, vFppi)
GO(gtk_image_set_pixel_size, vFpi)
-GO(gtk_image_type_get_type, pFv)
+GO(gtk_image_type_get_type, LFv)
GO(gtk_im_context_delete_surrounding, iFpii)
GO(gtk_im_context_filter_key, iFpippuuii)
GO(gtk_im_context_filter_keypress, iFpp)
@@ -1465,7 +1475,7 @@ GO(gtk_im_context_focus_in, vFp)
GO(gtk_im_context_focus_out, vFp)
GO(gtk_im_context_get_preedit_string, vFpppp)
GO(gtk_im_context_get_surrounding, iFppp)
-GO(gtk_im_context_get_type, pFv)
+GO(gtk_im_context_get_type, LFv)
GO(gtk_im_context_reset, vFp)
GO(gtk_im_context_set_client_widget, vFpp)
GO(gtk_im_context_set_client_window, vFpp)
@@ -1473,23 +1483,23 @@ GO(gtk_im_context_set_cursor_location, vFpp)
GO(gtk_im_context_set_surrounding, vFppii)
GO(gtk_im_context_set_use_preedit, vFpi)
GO(gtk_im_context_simple_add_table, vFppii)
-GO(gtk_im_context_simple_get_type, pFv)
+GO(gtk_im_context_simple_get_type, LFv)
GO(gtk_im_context_simple_new, pFv)
GO(gtk_im_multicontext_append_menuitems, vFpp)
GO(gtk_im_multicontext_get_context_id, pFp)
-GO(gtk_im_multicontext_get_type, pFv)
+GO(gtk_im_multicontext_get_type, LFv)
GO(gtk_im_multicontext_new, pFv)
GO(gtk_im_multicontext_set_context_id, vFpp)
-GO(gtk_im_preedit_style_get_type, pFv)
-GO(gtk_im_status_style_get_type, pFv)
+GO(gtk_im_preedit_style_get_type, LFv)
+GO(gtk_im_status_style_get_type, LFv)
GO(gtk_info_bar_add_action_widget, vFppi)
GO(gtk_info_bar_add_button, pFppi)
//GO(gtk_info_bar_add_buttons,
//GO(gtk_info_bar_get_action_area,
GO(gtk_info_bar_get_content_area, pFp)
GO(gtk_info_bar_get_message_type, uFp)
-GO(gtk_info_bar_get_type, pFv)
-//GO(gtk_info_bar_new,
+GO(gtk_info_bar_get_type, LFv)
+GO(gtk_info_bar_new, pFv)
//GO(gtk_info_bar_new_with_buttons,
GO(gtk_info_bar_response, vFpi)
//GO(gtk_info_bar_set_default_response,
@@ -1500,13 +1510,13 @@ GOM(gtk_init, vFEpp)
GOM(gtk_init_check, iFEpp)
GOM(gtk_init_with_args, iFEpppppp)
//GOM(gtk_input_add_full, uFEiBBppB)
-GO(gtk_input_dialog_get_type, pFv)
+GO(gtk_input_dialog_get_type, LFv)
GO(gtk_input_dialog_new, pFv)
-GO(gtk_input_hints_get_type, pFv)
-GO(gtk_input_purpose_get_type, pFv)
+GO(gtk_input_hints_get_type, LFv)
+GO(gtk_input_purpose_get_type, LFv)
GO(gtk_input_remove, vFu)
GO(gtk_invisible_get_screen, pFp)
-GO(gtk_invisible_get_type, pFv)
+GO(gtk_invisible_get_type, LFv)
//GO(gtk_invisible_new,
GO(gtk_invisible_new_for_screen, pFp)
GO(gtk_invisible_set_screen, vFpp)
@@ -1525,7 +1535,7 @@ GO(gtk_invisible_set_screen, vFpp)
//GO(gtk_item_factory_from_widget,
//GO(gtk_item_factory_get_item,
//GO(gtk_item_factory_get_item_by_action,
-GO(gtk_item_factory_get_type, pFv)
+GO(gtk_item_factory_get_type, LFv)
//GO(gtk_item_factory_get_widget,
//GO(gtk_item_factory_get_widget_by_action,
//GO(gtk_item_factory_new,
@@ -1535,10 +1545,10 @@ GO(gtk_item_factory_get_type, pFv)
//GO(gtk_item_factory_popup_data_from_widget,
//GO(gtk_item_factory_popup_with_data,
//GO(gtk_item_factory_set_translate_func,
-GO(gtk_item_get_type, pFv)
+GO(gtk_item_get_type, LFv)
//GO(gtk_item_select,
//GO(gtk_item_toggle,
-GO(gtk_justification_get_type, pFv)
+GO(gtk_justification_get_type, LFv)
//GOM(gtk_key_snooper_install, uFEBp)
GO(gtk_key_snooper_remove, vFu)
GO(gtk_label_get, vFpp)
@@ -1560,7 +1570,7 @@ GO(gtk_label_get_selection_bounds, iFppp)
GO(gtk_label_get_single_line_mode, iFp)
GO(gtk_label_get_text, pFp)
GO(gtk_label_get_track_visited_links, iFp)
-GO(gtk_label_get_type, pFv)
+GO(gtk_label_get_type, LFv)
GO(gtk_label_get_use_markup, iFp)
GO(gtk_label_get_use_underline, iFp)
GO(gtk_label_get_width_chars, iFp)
@@ -1592,7 +1602,7 @@ GO(gtk_label_set_width_chars, vFpi)
GO(gtk_layout_get_bin_window, pFp)
//GO(gtk_layout_get_hadjustment,
GO(gtk_layout_get_size, vFppp)
-GO(gtk_layout_get_type, pFv)
+GO(gtk_layout_get_type, LFv)
GO(gtk_layout_get_vadjustment, pFp)
GO(gtk_layout_move, vFppii)
GO(gtk_layout_new, pFpp)
@@ -1601,30 +1611,30 @@ GO(gtk_layout_new, pFpp)
GO(gtk_layout_set_size, vFpuu)
GO(gtk_layout_set_vadjustment, vFpp)
//GO(gtk_layout_thaw,
-GO(gtk_level_bar_mode_get_type, pFv)
-GO(gtk_level_bar_get_type, pFv)
-GO(gtk_license_get_type, pFv)
-GO(gtk_link_button_get_type, pFv)
+GO(gtk_level_bar_mode_get_type, LFv)
+GO(gtk_level_bar_get_type, LFv)
+GO(gtk_license_get_type, LFv)
+GO(gtk_link_button_get_type, LFv)
GO(gtk_link_button_get_uri, pFp)
GO(gtk_link_button_get_visited, iFp)
-//GO(gtk_link_button_new,
-//GO(gtk_link_button_new_with_label,
+GO(gtk_link_button_new, pFp)
+GO(gtk_link_button_new_with_label, pFpp)
GO(gtk_link_button_set_uri, vFpp)
//GO(gtk_link_button_set_uri_hook,
GO(gtk_link_button_set_visited, vFpi)
GO(gtk_list_append_items, vFpp)
-GO(gtk_list_box_get_type, pFv)
-GO(gtk_list_box_row_get_type, pFv)
+GO(gtk_list_box_get_type, LFv)
+GO(gtk_list_box_row_get_type, LFv)
GO(gtk_list_box_set_header_func, vFppp)
GO(gtk_list_child_position, iFpp)
GO(gtk_list_clear_items, vFpii)
GO(gtk_list_end_drag_selection, vFp)
GO(gtk_list_end_selection, vFp)
GO(gtk_list_extend_selection, vFpifi)
-GO(gtk_list_get_type, pFv)
+GO(gtk_list_get_type, LFv)
GO(gtk_list_insert_items, vFppi)
GO(gtk_list_item_deselect, vFp)
-GO(gtk_list_item_get_type, pFv)
+GO(gtk_list_item_get_type, LFv)
GO(gtk_list_item_new, pFv)
GO(gtk_list_item_new_with_label, pFp)
GO(gtk_list_item_select, vFp)
@@ -1641,7 +1651,7 @@ GO(gtk_list_set_selection_mode, vFpi)
GO(gtk_list_start_selection, vFp)
GO(gtk_list_store_append, vFpp)
GO(gtk_list_store_clear, vFp)
-GO(gtk_list_store_get_type, pFv)
+GO(gtk_list_store_get_type, LFv)
GO(gtk_list_store_insert, vFppi)
GO(gtk_list_store_insert_after, vFppp)
GO(gtk_list_store_insert_before, vFppp)
@@ -1700,20 +1710,20 @@ GO(gtk_main_quit, vFv)
//GO(gtk_marshal_VOID__UINT_POINTER_UINT_ENUM_ENUM_POINTER,
//GO(gtk_marshal_VOID__UINT_POINTER_UINT_UINT_ENUM,
//GO(gtk_marshal_VOID__UINT_STRING,
-GO(gtk_match_type_get_type, pFv)
+GO(gtk_match_type_get_type, LFv)
GO(gtk_menu_attach, vFppuuuu)
GOM(gtk_menu_attach_to_widget, vFEppp)
GO(gtk_menu_bar_get_child_pack_direction, uFp)
GO(gtk_menu_bar_get_pack_direction, iFp)
-GO(gtk_menu_bar_get_type, pFv)
+GO(gtk_menu_bar_get_type, LFv)
GO(gtk_menu_bar_new, pFv)
GO(gtk_menu_bar_set_child_pack_direction, vFpu)
GO(gtk_menu_bar_set_pack_direction, vFpi)
GO(gtk_menu_button_new, pFv)
GO(gtk_menu_button_set_menu_model, vFpp)
-GO(gtk_menu_button_get_type, pFv)
+GO(gtk_menu_button_get_type, LFv)
GO(gtk_menu_detach, vFp)
-GO(gtk_menu_direction_type_get_type, pFv)
+GO(gtk_menu_direction_type_get_type, LFv)
GO(gtk_menu_get_accel_group, pFp)
GO(gtk_menu_get_accel_path, pFp)
GO(gtk_menu_get_active, pFp)
@@ -1723,14 +1733,14 @@ GO(gtk_menu_get_monitor, iFp)
GO(gtk_menu_get_reserve_toggle_size, iFp)
GO(gtk_menu_get_tearoff_state, iFp)
GO(gtk_menu_get_title, pFp)
-GO(gtk_menu_get_type, pFv)
+GO(gtk_menu_get_type, LFv)
GO(gtk_menu_item_activate, vFp)
GO(gtk_menu_item_deselect, vFp)
GO(gtk_menu_item_get_accel_path, pFp)
GO(gtk_menu_item_get_label, pFp)
GO(gtk_menu_item_get_right_justified, iFp)
GO(gtk_menu_item_get_submenu, pFp)
-GO(gtk_menu_item_get_type, pFv)
+GO(gtk_menu_item_get_type, LFv)
GO(gtk_menu_item_get_use_underline, vFpi)
GO(gtk_menu_item_new, pFv)
GO(gtk_menu_item_new_with_label, pFp)
@@ -1763,14 +1773,14 @@ GO(gtk_menu_shell_append, vFpp)
//GO(gtk_menu_shell_deactivate,
//GO(gtk_menu_shell_deselect,
GO(gtk_menu_shell_get_take_focus, iFp)
-GO(gtk_menu_shell_get_type, pFv)
+GO(gtk_menu_shell_get_type, LFv)
GO(gtk_menu_shell_insert, vFppi)
GO(gtk_menu_shell_prepend, vFpp)
GO(gtk_menu_shell_select_first, vFpi)
GO(gtk_menu_shell_select_item, vFpp)
GO(gtk_menu_shell_set_take_focus, vFpi)
GO(gtk_menu_tool_button_get_menu, pFp)
-GO(gtk_menu_tool_button_get_type, pFv)
+GO(gtk_menu_tool_button_get_type, LFv)
GO(gtk_menu_tool_button_new, pFpp)
//GO(gtk_menu_tool_button_new_from_stock,
//GO(gtk_menu_tool_button_set_arrow_tooltip,
@@ -1781,26 +1791,37 @@ GOM(gtk_message_dialog_format_secondary_markup, vFEppV)
GOM(gtk_message_dialog_format_secondary_text, vFEppV)
GO(gtk_message_dialog_get_image, pFp)
GO(gtk_message_dialog_get_message_area, pFp)
-GO(gtk_message_dialog_get_type, pFv)
+GO(gtk_message_dialog_get_type, LFv)
GO(gtk_message_dialog_new, pFpuiippppppppppp) // vaarg :(
GO(gtk_message_dialog_new_with_markup, pFpuiippppppppppp) // vaarg
GO(gtk_message_dialog_set_image, vFpp)
GO(gtk_message_dialog_set_markup, vFpp)
-GO(gtk_message_type_get_type, pFv)
-GO(gtk_metric_type_get_type, pFv)
+GO(gtk_message_type_get_type, LFv)
+GO(gtk_metric_type_get_type, LFv)
GO(gtk_misc_get_alignment, vFppp)
GO(gtk_misc_get_padding, vFppp)
-GO(gtk_misc_get_type, pFv)
+GO(gtk_misc_get_type, LFv)
GO(gtk_misc_set_alignment, vFpff)
GO(gtk_misc_set_padding, vFpii)
GO(gtk_mount_operation_get_parent, pFp)
GO(gtk_mount_operation_get_screen, pFp)
-GO(gtk_mount_operation_get_type, pFv)
+GO(gtk_mount_operation_get_type, LFv)
GO(gtk_mount_operation_is_showing, iFp)
GO(gtk_mount_operation_new, pFp)
GO(gtk_mount_operation_set_parent, vFpp)
GO(gtk_mount_operation_set_screen, vFpp)
-GO(gtk_movement_step_get_type, pFv)
+GO(gtk_movement_step_get_type, LFv)
+GO(gtk_native_dialog_destroy, vFp)
+GO(gtk_native_dialog_get_modal, iFp)
+GO(gtk_native_dialog_get_title, pFp)
+GO(gtk_native_dialog_get_transient_for, pFp)
+GO(gtk_native_dialog_get_visible, iFp)
+GO(gtk_native_dialog_hide, vFp)
+GO(gtk_native_dialog_run, iFp)
+GO(gtk_native_dialog_set_modal, vFpi)
+GO(gtk_native_dialog_set_title, vFpp)
+GO(gtk_native_dialog_set_transient_for, vFpp)
+GO(gtk_native_dialog_show, vFp)
GO(gtk_native_get_surface, pFp)
GO(gtk_notebook_append_page, iFppp)
GO(gtk_notebook_append_page_menu, iFpppp)
@@ -1823,7 +1844,7 @@ GO(gtk_notebook_get_tab_label_text, pFpp)
GO(gtk_notebook_get_tab_pos, uFp)
GO(gtk_notebook_get_tab_reorderable, iFpp)
GO(gtk_notebook_get_tab_vborder, WFp)
-GO(gtk_notebook_get_type, pFv)
+GO(gtk_notebook_get_type, LFv)
GO(gtk_notebook_insert_page, iFpppi)
GO(gtk_notebook_insert_page_menu, iFppppi)
GO(gtk_notebook_new, pFv)
@@ -1858,15 +1879,15 @@ GO(gtk_notebook_set_tab_pos, vFpu)
GO(gtk_notebook_set_tab_reorderable, vFppi)
GO(gtk_notebook_set_tab_vborder, vFpu)
//GOM(gtk_notebook_set_window_creation_hook, pFEppp)
-GO(gtk_notebook_tab_get_type, pFv)
-GO(gtk_number_up_layout_get_type, pFv)
+GO(gtk_notebook_tab_get_type, LFv)
+GO(gtk_number_up_layout_get_type, LFv)
GO(gtk_object_add_arg_type, vFpiuu)
GO(gtk_object_destroy, vFp)
-GO(gtk_object_flags_get_type, pFv)
+GO(gtk_object_flags_get_type, LFv)
GO(gtk_object_get, vFppppppppppp) // vaarg
GO(gtk_object_get_data, pFpp)
GO(gtk_object_get_data_by_id, pFpp)
-GO(gtk_object_get_type, pFv)
+GO(gtk_object_get_type, LFv)
GO(gtk_object_get_user_data, pFp)
GO(gtk_object_new, pFppppppppppp) //vaarg
GO(gtk_object_ref, pFp)
@@ -1886,28 +1907,28 @@ GO(gtk_object_unref, vFp)
//GOM(gtk_object_weakunref, vFEppp)
GO(gtk_offscreen_window_get_pixbuf, pFp)
GO(gtk_offscreen_window_get_pixmap, pFp)
-GO(gtk_offscreen_window_get_type, pFv)
+GO(gtk_offscreen_window_get_type, LFv)
GO(gtk_offscreen_window_new, pFv)
GO(gtk_old_editable_changed, vFp)
GO(gtk_old_editable_claim_selection, vFpiu)
-GO(gtk_old_editable_get_type, pFv)
+GO(gtk_old_editable_get_type, LFv)
GO(gtk_option_menu_get_history, iFp)
GO(gtk_option_menu_get_menu, pFp)
-GO(gtk_option_menu_get_type, pFv)
+GO(gtk_option_menu_get_type, LFv)
GO(gtk_option_menu_new, pFv)
GO(gtk_option_menu_remove_menu, vFp)
GO(gtk_option_menu_set_history, vFpu)
GO(gtk_option_menu_set_menu, vFpp)
GO(gtk_orientable_get_orientation, uFp)
-GO(gtk_orientable_get_type, pFv)
+GO(gtk_orientable_get_type, LFv)
GO(gtk_orientable_set_orientation, vFpu)
-GO(gtk_orientation_get_type, pFv)
+GO(gtk_orientation_get_type, LFv)
GO(gtk_overlay_add_overlay, vFpp)
-GO(gtk_overlay_get_type, pFv)
-GO(gtk_pack_direction_get_type, pFv)
-GO(gtk_pack_type_get_type, pFv)
-GO(gtk_page_orientation_get_type, pFv)
-GO(gtk_page_set_get_type, pFv)
+GO(gtk_overlay_get_type, LFv)
+GO(gtk_pack_direction_get_type, LFv)
+GO(gtk_pack_type_get_type, LFv)
+GO(gtk_page_orientation_get_type, LFv)
+GO(gtk_page_set_get_type, LFv)
GO(gtk_page_setup_copy, pFp)
//GO(gtk_page_setup_get_bottom_margin,
GO(gtk_page_setup_get_left_margin, dFpi)
@@ -1919,7 +1940,7 @@ GO(gtk_page_setup_get_paper_size, pFp)
GO(gtk_page_setup_get_paper_width, dFpi)
GO(gtk_page_setup_get_right_margin, dFpi)
GO(gtk_page_setup_get_top_margin, dFpi)
-GO(gtk_page_setup_get_type, pFv)
+GO(gtk_page_setup_get_type, LFv)
//GO(gtk_page_setup_load_file,
GO(gtk_page_setup_load_key_file, iFpppp)
GO(gtk_page_setup_new, pFv)
@@ -1936,7 +1957,7 @@ GO(gtk_page_setup_to_file, iFppp)
GO(gtk_page_setup_to_key_file, vFppp)
//GO(gtk_page_setup_unix_dialog_get_page_setup,
//GO(gtk_page_setup_unix_dialog_get_print_settings,
-GO(gtk_page_setup_unix_dialog_get_type, pFv)
+GO(gtk_page_setup_unix_dialog_get_type, LFv)
//GO(gtk_page_setup_unix_dialog_new,
//GO(gtk_page_setup_unix_dialog_set_page_setup,
//GO(gtk_page_setup_unix_dialog_set_print_settings,
@@ -1969,7 +1990,8 @@ GO(gtk_paned_get_child1, pFp)
GO(gtk_paned_get_child2, pFp)
GO(gtk_paned_get_handle_window, pFp)
GO(gtk_paned_get_position, iFp)
-GO(gtk_paned_get_type, pFv)
+GO(gtk_paned_get_type, LFv)
+GO(gtk_paned_new, pFi)
GO(gtk_paned_pack1, vFppii)
GO(gtk_paned_pack2, vFppii)
GO(gtk_paned_set_position, vFpi)
@@ -1985,7 +2007,7 @@ GO(gtk_paper_size_get_height, dFpi)
GO(gtk_paper_size_get_name, pFp)
GO(gtk_paper_size_get_paper_sizes, pFi)
GO(gtk_paper_size_get_ppd_name, pFp)
-GO(gtk_paper_size_get_type, pFv)
+GO(gtk_paper_size_get_type, LFv)
GO(gtk_paper_size_get_width, dFpi)
GO(gtk_paper_size_is_custom, iFp)
GO(gtk_paper_size_is_equal, iFpp)
@@ -1996,11 +2018,11 @@ GO(gtk_paper_size_new_from_ppd, pFppdd)
GO(gtk_paper_size_set_size, vFpddu)
GO(gtk_paper_size_to_key_file, vFppp)
GO(gtk_parse_args, iFpp)
-GO(gtk_path_bar_get_type, pFv)
-GO(gtk_path_priority_type_get_type, pFv)
-GO(gtk_path_type_get_type, pFv)
+GO(gtk_path_bar_get_type, LFv)
+GO(gtk_path_priority_type_get_type, LFv)
+GO(gtk_path_type_get_type, LFv)
GO(gtk_pixmap_get, vFppp)
-GO(gtk_pixmap_get_type, pFv)
+GO(gtk_pixmap_get_type, LFv)
GO(gtk_pixmap_new, pFpp)
GO(gtk_pixmap_set, vFppp)
GO(gtk_pixmap_set_build_insensitive, vFpi)
@@ -2009,16 +2031,16 @@ GO(gtk_plug_construct_for_display, vFppp)
GO(gtk_plug_get_embedded, iFp)
GO(gtk_plug_get_id, pFp)
GO(gtk_plug_get_socket_window, pFp)
-GO(gtk_plug_get_type, pFv)
+GO(gtk_plug_get_type, LFv)
GO(gtk_plug_new, pFp)
GO(gtk_plug_new_for_display, pFpp)
-GO(gtk_policy_type_get_type, pFv)
-GO(gtk_popover_get_type, pFv)
-GO(gtk_position_type_get_type, pFv)
+GO(gtk_policy_type_get_type, LFv)
+GO(gtk_popover_get_type, LFv)
+GO(gtk_position_type_get_type, LFv)
//GO(gtk_preview_draw_row,
//GO(gtk_preview_get_cmap,
//GO(gtk_preview_get_info,
-GO(gtk_preview_get_type, pFv)
+GO(gtk_preview_get_type, LFv)
//GO(gtk_preview_get_visual,
//GO(gtk_preview_new,
//GO(gtk_preview_put,
@@ -2030,21 +2052,21 @@ GO(gtk_preview_get_type, pFv)
//GO(gtk_preview_set_install_cmap,
//GO(gtk_preview_set_reserved,
//GO(gtk_preview_size,
-GO(gtk_preview_type_get_type, pFv)
+GO(gtk_preview_type_get_type, LFv)
//GO(gtk_preview_uninit,
//GO(gtk_print_backend_add_printer,
//GO(gtk_print_backend_destroy,
//GO(gtk_print_backend_error_quark,
//GO(gtk_print_backend_find_printer,
//GO(gtk_print_backend_get_printer_list,
-GO(gtk_print_backend_get_type, pFv)
+GO(gtk_print_backend_get_type, LFv)
//GO(gtk_print_backend_load_modules,
//GO(gtk_print_backend_printer_list_is_done,
//GO(gtk_print_backend_print_stream,
//GO(gtk_print_backend_remove_printer,
//GO(gtk_print_backend_set_list_done,
//GO(gtk_print_backend_set_password,
-GO(gtk_print_capabilities_get_type, pFv)
+GO(gtk_print_capabilities_get_type, LFv)
GO(gtk_print_context_create_pango_context, pFp)
GO(gtk_print_context_create_pango_layout, pFp)
GO(gtk_print_context_get_cairo_context, pFp)
@@ -2054,10 +2076,10 @@ GO(gtk_print_context_get_hard_margins, iFppppp)
//GO(gtk_print_context_get_height,
GO(gtk_print_context_get_page_setup, pFp)
GO(gtk_print_context_get_pango_fontmap, pFp)
-GO(gtk_print_context_get_type, pFv)
+GO(gtk_print_context_get_type, LFv)
//GO(gtk_print_context_get_width,
GO(gtk_print_context_set_cairo_context, vFppdd)
-GO(gtk_print_duplex_get_type, pFv)
+GO(gtk_print_duplex_get_type, LFv)
//GO(gtk_printer_accepts_pdf,
//GO(gtk_printer_accepts_ps,
//GO(gtk_printer_compare,
@@ -2071,7 +2093,7 @@ GO(gtk_printer_get_default_page_size, pFp)
//GO(gtk_printer_get_location,
GO(gtk_printer_get_name, pFp)
//GO(gtk_printer_get_state_message,
-GO(gtk_printer_get_type, pFv)
+GO(gtk_printer_get_type, LFv)
//GO(gtk_printer_has_details,
//GO(gtk_printer_is_accepting_jobs,
//GO(gtk_printer_is_active,
@@ -2085,7 +2107,7 @@ GO(gtk_printer_is_default, iFp)
//GO(gtk_printer_option_choices_from_array,
//GO(gtk_printer_option_clear_has_conflict,
//GO(gtk_printer_option_get_activates_default,
-GO(gtk_printer_option_get_type, pFv)
+GO(gtk_printer_option_get_type, LFv)
//GO(gtk_printer_option_has_choice,
//GO(gtk_printer_option_new,
//GO(gtk_printer_option_set,
@@ -2096,19 +2118,19 @@ GO(gtk_printer_option_get_type, pFv)
//GO(gtk_printer_option_set_foreach,
//GO(gtk_printer_option_set_foreach_in_group,
//GO(gtk_printer_option_set_get_groups,
-GO(gtk_printer_option_set_get_type, pFv)
+GO(gtk_printer_option_set_get_type, LFv)
//GO(gtk_printer_option_set_has_conflict,
//GO(gtk_printer_option_set_lookup,
//GO(gtk_printer_option_set_new,
//GO(gtk_printer_option_set_remove,
//GO(gtk_printer_option_widget_get_external_label,
-GO(gtk_printer_option_widget_get_type, pFv)
+GO(gtk_printer_option_widget_get_type, LFv)
//GO(gtk_printer_option_widget_get_value,
//GO(gtk_printer_option_widget_has_external_label,
//GO(gtk_printer_option_widget_new,
//GO(gtk_printer_option_widget_set_source,
//GO(gtk_printer_request_details,
-GO(gtk_print_error_get_type, pFv)
+GO(gtk_print_error_get_type, LFv)
//GO(gtk_print_error_quark,
//GO(gtk_printer_set_accepts_pdf,
//GO(gtk_printer_set_accepts_ps,
@@ -2129,13 +2151,13 @@ GO(gtk_print_error_get_type, pFv)
//GO(gtk_print_job_get_surface,
//GO(gtk_print_job_get_title,
//GO(gtk_print_job_get_track_print_status,
-GO(gtk_print_job_get_type, pFv)
+GO(gtk_print_job_get_type, LFv)
GO(gtk_print_job_new, pFpppp)
GOM(gtk_print_job_send, vFEpppp)
GO(gtk_print_job_set_source_file, iFppp)
//GO(gtk_print_job_set_status,
//GO(gtk_print_job_set_track_print_status,
-GO(gtk_print_operation_action_get_type, pFv)
+GO(gtk_print_operation_action_get_type, LFv)
//GO(gtk_print_operation_cancel,
//GO(gtk_print_operation_draw_page_finish,
GO(gtk_print_operation_get_default_page_setup, pFp)
@@ -2147,14 +2169,14 @@ GO(gtk_print_operation_get_print_settings, pFp)
GO(gtk_print_operation_get_status, uFp)
GO(gtk_print_operation_get_status_string, pFp)
//GO(gtk_print_operation_get_support_selection,
-GO(gtk_print_operation_get_type, pFv)
+GO(gtk_print_operation_get_type, LFv)
//GO(gtk_print_operation_is_finished,
GO(gtk_print_operation_new, pFv)
//GO(gtk_print_operation_preview_end_preview,
-GO(gtk_print_operation_preview_get_type, pFv)
+GO(gtk_print_operation_preview_get_type, LFv)
GO(gtk_print_operation_preview_is_selected, iFpi)
GO(gtk_print_operation_preview_render_page, vFpi)
-GO(gtk_print_operation_result_get_type, pFv)
+GO(gtk_print_operation_result_get_type, LFv)
GO(gtk_print_operation_run, uFpupp)
//GO(gtk_print_operation_set_allow_async,
GO(gtk_print_operation_set_current_page, vFpi)
@@ -2172,8 +2194,8 @@ GO(gtk_print_operation_set_print_settings, vFpp)
//GO(gtk_print_operation_set_track_print_status,
GO(gtk_print_operation_set_unit, vFpu)
//GO(gtk_print_operation_set_use_full_page,
-GO(gtk_print_pages_get_type, pFv)
-GO(gtk_print_quality_get_type, pFv)
+GO(gtk_print_pages_get_type, LFv)
+GO(gtk_print_quality_get_type, LFv)
GO(gtk_print_run_page_setup_dialog, pFppp)
//GO(gtk_print_run_page_setup_dialog_async,
GO(gtk_print_settings_copy, pFp)
@@ -2210,7 +2232,7 @@ GO(gtk_print_settings_get_resolution, iFp)
GO(gtk_print_settings_get_resolution_y, iFp)
GO(gtk_print_settings_get_reverse, iFp)
GO(gtk_print_settings_get_scale, dFp)
-GO(gtk_print_settings_get_type, pFv)
+GO(gtk_print_settings_get_type, LFv)
//GO(gtk_print_settings_get_use_color,
//GO(gtk_print_settings_has_key,
//GO(gtk_print_settings_load_file,
@@ -2251,7 +2273,7 @@ GO(gtk_print_settings_set_scale, vFpd)
GO(gtk_print_settings_to_file, iFppp)
GO(gtk_print_settings_to_key_file, vFppp)
//GO(gtk_print_settings_unset,
-GO(gtk_print_status_get_type, pFv)
+GO(gtk_print_status_get_type, LFv)
//GO(gtk_print_unix_dialog_add_custom_tab,
//GO(gtk_print_unix_dialog_get_current_page,
//GO(gtk_print_unix_dialog_get_embed_page_setup,
@@ -2262,7 +2284,7 @@ GO(gtk_print_unix_dialog_get_page_setup, pFp)
GO(gtk_print_unix_dialog_get_selected_printer, pFp)
GO(gtk_print_unix_dialog_get_settings, pFp)
//GO(gtk_print_unix_dialog_get_support_selection,
-GO(gtk_print_unix_dialog_get_type, pFv)
+GO(gtk_print_unix_dialog_get_type, LFv)
GO(gtk_print_unix_dialog_new, pFpp)
//GO(gtk_print_unix_dialog_set_current_page,
GO(gtk_print_unix_dialog_set_embed_page_setup, vFpi)
@@ -2271,16 +2293,16 @@ GO(gtk_print_unix_dialog_set_manual_capabilities, vFpi)
//GO(gtk_print_unix_dialog_set_page_setup,
GO(gtk_print_unix_dialog_set_settings, vFpp)
GO(gtk_print_unix_dialog_set_support_selection, vFpi)
-GO(gtk_private_flags_get_type, pFv)
+GO(gtk_private_flags_get_type, LFv)
GO(gtk_progress_bar_get_ellipsize, uFp)
GO(gtk_progress_bar_get_fraction, dFp)
GO(gtk_progress_bar_get_orientation, iFp)
GO(gtk_progress_bar_get_pulse_step, dFp)
GO(gtk_progress_bar_get_text, pFp)
-GO(gtk_progress_bar_get_type, pFv)
+GO(gtk_progress_bar_get_type, LFv)
GO(gtk_progress_bar_new, pFv)
GO(gtk_progress_bar_new_with_adjustment, pFp)
-GO(gtk_progress_bar_orientation_get_type, pFv)
+GO(gtk_progress_bar_orientation_get_type, LFv)
GO(gtk_progress_bar_pulse, vFp)
GO(gtk_progress_bar_set_activity_blocks, vFpu)
GO(gtk_progress_bar_set_activity_step, vFpu)
@@ -2290,15 +2312,16 @@ GO(gtk_progress_bar_set_ellipsize, vFpu)
GO(gtk_progress_bar_set_fraction, vFpd)
GO(gtk_progress_bar_set_orientation, vFpi)
GO(gtk_progress_bar_set_pulse_step, vFpd)
+GO(gtk_progress_bar_set_show_text, vFpi)
GO(gtk_progress_bar_set_text, vFpp)
-GO(gtk_progress_bar_style_get_type, pFv)
+GO(gtk_progress_bar_style_get_type, LFv)
GO(gtk_progress_bar_update, vFpd)
//GO(gtk_progress_configure,
//GO(gtk_progress_get_current_percentage,
//GO(gtk_progress_get_current_text,
//GO(gtk_progress_get_percentage_from_value,
//GO(gtk_progress_get_text_from_value,
-GO(gtk_progress_get_type, pFv)
+GO(gtk_progress_get_type, LFv)
//GO(gtk_progress_get_value,
//GO(gtk_progress_set_activity_mode,
//GO(gtk_progress_set_adjustment,
@@ -2315,12 +2338,12 @@ GO(gtk_quit_remove, vFu)
GO(gtk_quit_remove_by_data, vFp)
GO(gtk_radio_action_get_current_value, iFp)
GO(gtk_radio_action_get_group, pFp)
-GO(gtk_radio_action_get_type, pFv)
+GO(gtk_radio_action_get_type, LFv)
GO(gtk_radio_action_new, pFppppi)
GO(gtk_radio_action_set_current_value, vFpi)
GO(gtk_radio_action_set_group, vFpp)
GO(gtk_radio_button_get_group, pFp)
-GO(gtk_radio_button_get_type, pFv)
+GO(gtk_radio_button_get_type, LFv)
GO(gtk_radio_button_new, pFp)
GO(gtk_radio_button_new_from_widget, pFp)
GO(gtk_radio_button_new_with_label, pFpp)
@@ -2329,7 +2352,7 @@ GO(gtk_radio_button_new_with_mnemonic, pFpp)
GO(gtk_radio_button_new_with_mnemonic_from_widget, pFpp)
GO(gtk_radio_button_set_group, vFpp)
GO(gtk_radio_menu_item_get_group, pFp)
-GO(gtk_radio_menu_item_get_type, pFv)
+GO(gtk_radio_menu_item_get_type, LFv)
GO(gtk_radio_menu_item_new, pFp)
GO(gtk_radio_menu_item_new_from_widget, pFp)
GO(gtk_radio_menu_item_new_with_label, pFpp)
@@ -2338,7 +2361,7 @@ GO(gtk_radio_menu_item_new_with_mnemonic, pFpp)
GO(gtk_radio_menu_item_new_with_mnemonic_from_widget, pFpp)
GO(gtk_radio_menu_item_set_group, vFpp)
GO(gtk_radio_tool_button_get_group, pFp)
-GO(gtk_radio_tool_button_get_type, pFv)
+GO(gtk_radio_tool_button_get_type, LFv)
GO(gtk_radio_tool_button_new, pFp)
GO(gtk_radio_tool_button_new_from_stock, pFpp)
GO(gtk_radio_tool_button_new_from_widget, pFp)
@@ -2356,7 +2379,7 @@ GO(gtk_range_get_round_digits, iFp)
GO(gtk_range_get_show_fill_level, iFp)
GO(gtk_range_get_slider_range, vFppp)
GO(gtk_range_get_slider_size_fixed, iFp)
-GO(gtk_range_get_type, pFv)
+GO(gtk_range_get_type, LFv)
GO(gtk_range_get_update_policy, iFp)
GO(gtk_range_get_upper_stepper_sensitivity, uFp)
GO(gtk_range_get_value, dFp)
@@ -2381,7 +2404,7 @@ GO(gtk_rc_add_widget_class_style, vFpp)
GO(gtk_rc_add_widget_name_style, vFpp)
GO(gtk_rc_find_module_in_path, pFp)
GO(gtk_rc_find_pixmap_in_path, pFppp)
-GO(gtk_rc_flags_get_type, pFv)
+GO(gtk_rc_flags_get_type, LFv)
GO(gtk_rc_get_default_files, pFv)
GO(gtk_rc_get_im_module_file, pFv)
GO(gtk_rc_get_im_module_path, pFv)
@@ -2406,23 +2429,23 @@ GO(gtk_rc_reset_styles, vFp)
GO(gtk_rc_scanner_new, pFv)
GO(gtk_rc_set_default_files, vFp)
GO(gtk_rc_style_copy, pFp)
-GO(gtk_rc_style_get_type, pFv)
+GO(gtk_rc_style_get_type, LFv)
GO(gtk_rc_style_new, pFv)
GO(gtk_rc_style_ref, vFp)
GO(gtk_rc_style_unref, vFp)
-GO(gtk_rc_token_type_get_type, pFv)
-GO(gtk_revealer_get_type, pFv)
-GO(gtk_revealer_transition_type_get_type, pFv)
+GO(gtk_rc_token_type_get_type, LFv)
+GO(gtk_revealer_get_type, LFv)
+GO(gtk_revealer_transition_type_get_type, LFv)
GO(gtk_recent_action_get_show_numbers, iFp)
-GO(gtk_recent_action_get_type, pFv)
+GO(gtk_recent_action_get_type, LFv)
GO(gtk_recent_action_new, pFpppp)
GO(gtk_recent_action_new_for_manager, pFppppp)
GO(gtk_recent_action_set_show_numbers, vFpi)
//GO(gtk_recent_chooser_add_filter,
-GO(gtk_recent_chooser_dialog_get_type, pFv)
+GO(gtk_recent_chooser_dialog_get_type, LFv)
//GO(gtk_recent_chooser_dialog_new,
//GO(gtk_recent_chooser_dialog_new_for_manager,
-GO(gtk_recent_chooser_error_get_type, pFv)
+GO(gtk_recent_chooser_error_get_type, LFv)
GO(gtk_recent_chooser_error_quark, uFv)
GO(gtk_recent_chooser_get_current_item, pFp)
GO(gtk_recent_chooser_get_current_uri, pFp)
@@ -2437,11 +2460,11 @@ GO(gtk_recent_chooser_get_show_icons, iFp)
//GO(gtk_recent_chooser_get_show_private,
//GO(gtk_recent_chooser_get_show_tips,
GO(gtk_recent_chooser_get_sort_type, uFp)
-GO(gtk_recent_chooser_get_type, pFv)
+GO(gtk_recent_chooser_get_type, LFv)
GO(gtk_recent_chooser_get_uris, pFpp)
GO(gtk_recent_chooser_list_filters, pFp)
GO(gtk_recent_chooser_menu_get_show_numbers, iFp)
-GO(gtk_recent_chooser_menu_get_type, pFv)
+GO(gtk_recent_chooser_menu_get_type, LFv)
//GO(gtk_recent_chooser_menu_new,
//GO(gtk_recent_chooser_menu_new_for_manager,
GO(gtk_recent_chooser_menu_set_show_numbers, vFpi)
@@ -2462,7 +2485,7 @@ GO(gtk_recent_chooser_set_show_icons, vFpi)
GO(gtk_recent_chooser_set_sort_type, vFpu)
//GO(gtk_recent_chooser_unselect_all,
GO(gtk_recent_chooser_unselect_uri, vFpp)
-GO(gtk_recent_chooser_widget_get_type, pFv)
+GO(gtk_recent_chooser_widget_get_type, LFv)
//GO(gtk_recent_chooser_widget_new,
GO(gtk_recent_chooser_widget_new_for_manager, pFp)
GO(gtk_recent_filter_add_age, vFpi)
@@ -2473,10 +2496,10 @@ GO(gtk_recent_filter_add_group, vFpp)
//GO(gtk_recent_filter_add_pattern,
//GO(gtk_recent_filter_add_pixbuf_formats,
GO(gtk_recent_filter_filter, iFpp)
-GO(gtk_recent_filter_flags_get_type, pFv)
+GO(gtk_recent_filter_flags_get_type, LFv)
GO(gtk_recent_filter_get_name, pFp)
GO(gtk_recent_filter_get_needed, uFp)
-GO(gtk_recent_filter_get_type, pFv)
+GO(gtk_recent_filter_get_type, LFv)
GO(gtk_recent_filter_new, pFv)
//GO(gtk_recent_filter_set_name,
GO(gtk_recent_info_exists, iFp)
@@ -2492,7 +2515,7 @@ GO(gtk_recent_info_get_mime_type, pFp)
//GO(gtk_recent_info_get_modified,
//GO(gtk_recent_info_get_private_hint,
//GO(gtk_recent_info_get_short_name,
-GO(gtk_recent_info_get_type, pFv)
+GO(gtk_recent_info_get_type, LFv)
//GO(gtk_recent_info_get_uri,
GO(gtk_recent_info_get_uri_display, pFp)
GO(gtk_recent_info_get_visited, lFp)
@@ -2505,13 +2528,13 @@ GO(gtk_recent_info_ref, pFp)
GO(gtk_recent_info_unref, vFp)
GO(gtk_recent_manager_add_full, iFppp)
//GO(gtk_recent_manager_add_item,
-GO(gtk_recent_manager_error_get_type, pFv)
+GO(gtk_recent_manager_error_get_type, LFv)
//GO(gtk_recent_manager_error_quark,
GO(gtk_recent_manager_get_default, pFv)
//GO(gtk_recent_manager_get_for_screen,
GO(gtk_recent_manager_get_items, pFp)
//GO(gtk_recent_manager_get_limit,
-GO(gtk_recent_manager_get_type, pFv)
+GO(gtk_recent_manager_get_type, LFv)
GO(gtk_recent_manager_has_item, iFpp)
GO(gtk_recent_manager_lookup_item, pFppp)
GO(gtk_recent_manager_move_item, iFpppp)
@@ -2520,8 +2543,8 @@ GO(gtk_recent_manager_purge_items, iFpp)
GO(gtk_recent_manager_remove_item, iFppp)
//GO(gtk_recent_manager_set_limit,
//GO(gtk_recent_manager_set_screen,
-GO(gtk_recent_sort_type_get_type, pFv)
-GO(gtk_relief_style_get_type, pFv)
+GO(gtk_recent_sort_type_get_type, LFv)
+GO(gtk_relief_style_get_type, LFv)
GO(gtk_render_activity, vFppdddd)
GO(gtk_render_arrow, vFppdddd)
GO(gtk_render_background, vFppdddd)
@@ -2543,15 +2566,15 @@ GO(gtk_render_option, vFppdddd)
GO(gtk_render_slider, vFppddddu)
GO(gtk_requisition_copy, pFp)
GO(gtk_requisition_free, vFp)
-GO(gtk_requisition_get_type, pFv)
-GO(gtk_resize_mode_get_type, pFv)
-GO(gtk_response_type_get_type, pFv)
+GO(gtk_requisition_get_type, LFv)
+GO(gtk_resize_mode_get_type, LFv)
+GO(gtk_response_type_get_type, LFv)
GO(gtk_rgb_to_hsv, vFdddppp)
//GO(gtk_ruler_draw_pos,
//GO(gtk_ruler_draw_ticks,
//GO(gtk_ruler_get_metric,
//GO(gtk_ruler_get_range,
-GO(gtk_ruler_get_type, pFv)
+GO(gtk_ruler_get_type, LFv)
//GO(gtk_ruler_set_metric,
//GO(gtk_ruler_set_range,
GO(gtk_scale_add_mark, vFpdup)
@@ -2560,7 +2583,7 @@ GO(gtk_scale_button_get_adjustment, pFp)
//GO(gtk_scale_button_get_orientation,
//GO(gtk_scale_button_get_plus_button,
GO(gtk_scale_button_get_popup, pFp)
-GO(gtk_scale_button_get_type, pFv)
+GO(gtk_scale_button_get_type, LFv)
GO(gtk_scale_button_get_value, dFp)
GO(gtk_scale_button_new, pFudddp)
GO(gtk_scale_button_set_adjustment, vFpp)
@@ -2569,22 +2592,25 @@ GO(gtk_scale_button_set_icons, vFpp)
GO(gtk_scale_button_set_value, vFpd)
//GO(gtk_scale_clear_marks,
GO(gtk_scale_get_digits, iFp)
-//GO(gtk_scale_get_draw_value,
+GO(gtk_scale_get_draw_value, iFp)
GO(gtk_scale_get_layout, pFp)
GO(gtk_scale_get_layout_offsets, vFppp)
-GO(gtk_scale_get_type, pFv)
+GO(gtk_scale_get_type, LFv)
GO(gtk_scale_get_value_pos, uFp)
+GO(gtk_scale_new, pFip)
GO(gtk_scale_set_digits, vFpi)
-//GO(gtk_scale_set_draw_value,
+GO(gtk_scale_set_draw_value, vFpi)
GO(gtk_scale_set_value_pos, vFpu)
-GO(gtk_scrollbar_get_type, pFv)
+GO(gtk_scrollable_get_type, LFv)
+GO(gtk_scrollbar_get_type, LFv)
+GO(gtk_scrollbar_new, pFip)
GO(gtk_scrolled_window_add_with_viewport, vFpp)
GO(gtk_scrolled_window_get_hadjustment, pFp)
GO(gtk_scrolled_window_get_hscrollbar, pFp)
GO(gtk_scrolled_window_get_placement, uFp)
GO(gtk_scrolled_window_get_policy, vFppp)
GO(gtk_scrolled_window_get_shadow_type, uFp)
-GO(gtk_scrolled_window_get_type, pFv)
+GO(gtk_scrolled_window_get_type, LFv)
GO(gtk_scrolled_window_get_vadjustment, pFp)
GO(gtk_scrolled_window_get_vscrollbar, pFp)
GO(gtk_scrolled_window_new, pFpp)
@@ -2594,10 +2620,10 @@ GO(gtk_scrolled_window_set_policy, vFpuu)
GO(gtk_scrolled_window_set_shadow_type, vFpu)
GO(gtk_scrolled_window_set_vadjustment, vFpp)
GO(gtk_scrolled_window_unset_placement, vFp)
-GO(gtk_scroll_step_get_type, pFv)
-GO(gtk_scroll_type_get_type, pFv)
-GO(gtk_search_bar_get_type, pFv)
-GO(gtk_search_entry_get_type, pFv)
+GO(gtk_scroll_step_get_type, LFv)
+GO(gtk_scroll_type_get_type, LFv)
+GO(gtk_search_bar_get_type, LFv)
+GO(gtk_search_entry_get_type, LFv)
GO(gtk_selection_add_target, vFpppu)
GO(gtk_selection_add_targets, vFpppu)
GO(gtk_selection_clear, iFpp)
@@ -2615,7 +2641,7 @@ GO(gtk_selection_data_get_selection, pFp)
GO(gtk_selection_data_get_target, pFp)
GO(gtk_selection_data_get_targets, iFppp)
GO(gtk_selection_data_get_text, pFp)
-GO(gtk_selection_data_get_type, pFv)
+GO(gtk_selection_data_get_type, LFv)
GO(gtk_selection_data_get_uris, pFp)
GO(gtk_selection_data_set, vFppipi)
GO(gtk_selection_data_set_pixbuf, iFpp)
@@ -2625,34 +2651,34 @@ GO(gtk_selection_data_targets_include_image, iFpi)
GO(gtk_selection_data_targets_include_rich_text, iFpp)
GO(gtk_selection_data_targets_include_text, iFp)
GO(gtk_selection_data_targets_include_uri, iFp)
-GO(gtk_selection_mode_get_type, pFv)
+GO(gtk_selection_mode_get_type, LFv)
GO(gtk_selection_owner_set, iFppu)
GO(gtk_selection_owner_set_for_display, iFpppu)
GO(gtk_selection_remove_all, vFp)
-GO(gtk_sensitivity_type_get_type, pFv)
-GO(gtk_separator_get_type, pFv)
-GO(gtk_separator_menu_item_get_type, pFv)
+GO(gtk_sensitivity_type_get_type, LFv)
+GO(gtk_separator_get_type, LFv)
+GO(gtk_separator_menu_item_get_type, LFv)
GO(gtk_separator_menu_item_new, pFv)
GO(gtk_separator_new, pFu)
GO(gtk_separator_tool_item_get_draw, iFp)
-GO(gtk_separator_tool_item_get_type, pFv)
+GO(gtk_separator_tool_item_get_type, LFv)
GO(gtk_separator_tool_item_new, pFv)
GO(gtk_separator_tool_item_set_draw, vFpi)
GO(gtk_set_locale, pFv)
GO(gtk_settings_get_default, pFv)
GO(gtk_settings_get_for_screen, pFp)
-GO(gtk_settings_get_type, pFv)
+GO(gtk_settings_get_type, LFv)
GO(gtk_settings_install_property, vFp)
//GOM(gtk_settings_install_property_parser, vFEpB)
GO(gtk_settings_set_double_property, vFppdp)
GO(gtk_settings_set_long_property, vFpplp)
GO(gtk_settings_set_property_value, vFppp)
GO(gtk_settings_set_string_property, vFpppp)
-GO(gtk_shadow_type_get_type, pFv)
+GO(gtk_shadow_type_get_type, LFv)
GO(gtk_show_about_dialog, vFpppppppppppppppppppppppp) //vaarg
GO(gtk_show_uri, iFppup)
GO(gtk_show_uri_on_window, iFppup)
-GO(gtk_side_type_get_type, pFv)
+GO(gtk_side_type_get_type, LFv)
//GO(gtk_signal_compat_matched,
GOM(gtk_signal_connect_full, LFEppppppii)
//GO(gtk_signal_connect_object_while_alive,
@@ -2664,13 +2690,13 @@ GOM(gtk_signal_connect_full, LFEppppppii)
//GO(gtk_signal_emitv_by_name,
//GO(gtk_signal_new,
//GO(gtk_signal_newv,
-GO(gtk_signal_run_type_get_type, pFv)
+GO(gtk_signal_run_type_get_type, LFv)
//GO(gtk_size_group_add_widget,
GO(gtk_size_group_get_ignore_hidden, iFp)
GO(gtk_size_group_get_mode, uFp)
-GO(gtk_size_group_get_type, pFv)
+GO(gtk_size_group_get_type, LFv)
GO(gtk_size_group_get_widgets, pFp)
-GO(gtk_size_group_mode_get_type, pFv)
+GO(gtk_size_group_mode_get_type, LFv)
GO(gtk_size_group_new, pFu)
GO(gtk_size_group_remove_widget, vFpp)
GO(gtk_size_group_set_ignore_hidden, vFpi)
@@ -2681,10 +2707,10 @@ GO(gtk_snapshot_render_background, vFppdddd)
GO(gtk_socket_add_id, vFpp)
GO(gtk_socket_get_id, pFp)
GO(gtk_socket_get_plug_window, pFp)
-GO(gtk_socket_get_type, pFv)
+GO(gtk_socket_get_type, LFv)
GO(gtk_socket_new, pFv)
GO(gtk_socket_steal, vFpp)
-GO(gtk_sort_type_get_type, pFv)
+GO(gtk_sort_type_get_type, LFv)
GO(gtk_spin_button_configure, vFppdu)
GO(gtk_spin_button_get_adjustment, pFp)
GO(gtk_spin_button_get_digits, uFp)
@@ -2692,7 +2718,7 @@ GO(gtk_spin_button_get_increments, vFppp)
GO(gtk_spin_button_get_numeric, iFp)
GO(gtk_spin_button_get_range, vFppp)
GO(gtk_spin_button_get_snap_to_ticks, iFp)
-GO(gtk_spin_button_get_type, pFv)
+GO(gtk_spin_button_get_type, LFv)
GO(gtk_spin_button_get_update_policy, uFp)
GO(gtk_spin_button_get_value, dFp)
GO(gtk_spin_button_get_value_as_int, iFp)
@@ -2710,21 +2736,21 @@ GO(gtk_spin_button_set_value, vFpd)
GO(gtk_spin_button_set_wrap, vFpi)
GO(gtk_spin_button_spin, vFpud)
GO(gtk_spin_button_update, vFp)
-GO(gtk_spin_button_update_policy_get_type, pFv)
-GO(gtk_spinner_get_type, pFv)
+GO(gtk_spin_button_update_policy_get_type, LFv)
+GO(gtk_spinner_get_type, LFv)
GO(gtk_spinner_new, pFv)
GO(gtk_spinner_start, vFp)
GO(gtk_spinner_stop, vFp)
-GO(gtk_spin_type_get_type, pFv)
-GO(gtk_stack_get_type, pFv)
-GO(gtk_stack_switcher_get_type, pFv)
-GO(gtk_stack_transition_type_get_type, pFv)
-GO(gtk_state_flags_get_type, pFv)
-GO(gtk_state_type_get_type, pFv)
+GO(gtk_spin_type_get_type, LFv)
+GO(gtk_stack_get_type, LFv)
+GO(gtk_stack_switcher_get_type, LFv)
+GO(gtk_stack_transition_type_get_type, LFv)
+GO(gtk_state_flags_get_type, LFv)
+GO(gtk_state_type_get_type, LFv)
GO(gtk_statusbar_get_context_id, uFpp)
GO(gtk_statusbar_get_has_resize_grip, iFp)
GO(gtk_statusbar_get_message_area, pFp)
-GO(gtk_statusbar_get_type, pFv)
+GO(gtk_statusbar_get_type, LFv)
GO(gtk_statusbar_new, pFv)
GO(gtk_statusbar_pop, vFpu)
GO(gtk_statusbar_push, uFpup)
@@ -2744,7 +2770,7 @@ GO(gtk_status_icon_get_storage_type, uFp)
GO(gtk_status_icon_get_title, pFp)
GO(gtk_status_icon_get_tooltip_markup, pFp)
GO(gtk_status_icon_get_tooltip_text, pFp)
-GO(gtk_status_icon_get_type, pFv)
+GO(gtk_status_icon_get_type, LFv)
GO(gtk_status_icon_get_visible, iFp)
GO(gtk_status_icon_get_x11_window_id, uFp)
GO(gtk_status_icon_is_embedded, iFp)
@@ -2784,7 +2810,7 @@ GO(gtk_style_context_add_provider_for_display, vFppu)
GO(gtk_style_context_add_provider_for_screen, vFppu)
GO(gtk_style_context_add_region, vFppu)
GO(gtk_style_context_cancel_animations, vFpp)
-//GO2(gtk_style_context_get, vFppV, gtk_style_context_get_valist)
+GOM(gtk_style_context_get, vFEppV)
GO(gtk_style_context_get_border, vFpip)
GO(gtk_style_context_get_background_color, vFpip)
GO(gtk_style_context_get_border_color, vFpup)
@@ -2842,7 +2868,7 @@ GO(gtk_style_detach, vFp)
GO(gtk_style_get, vFpippppppppppp) //vaarg, wrap with gtk_style_get_valist?
GO(gtk_style_get_font, pFp)
GO(gtk_style_get_style_property, vFpLpp)
-GO(gtk_style_get_type, pFv)
+GO(gtk_style_get_type, LFv)
//GO(gtk_style_get_valist, vFpipA)
GO(gtk_style_lookup_color, iFppp)
GO(gtk_style_lookup_icon_set, pFpp)
@@ -2851,11 +2877,11 @@ GO(gtk_style_ref, pFp)
GO(gtk_style_render_icon, pFppuuupp)
GO(gtk_style_set_background, vFppu)
GO(gtk_style_set_font, vFpp)
-GO(gtk_style_provider_get_type, pFv)
+GO(gtk_style_provider_get_type, LFv)
GO(gtk_style_unref, vFp)
-GO(gtk_submenu_direction_get_type, pFv)
-GO(gtk_submenu_placement_get_type, pFv)
-GO(gtk_switch_get_type, pFv)
+GO(gtk_submenu_direction_get_type, LFv)
+GO(gtk_submenu_placement_get_type, LFv)
+GO(gtk_switch_get_type, LFv)
GO(gtk_table_attach, vFppuuuuuuuu)
GO(gtk_table_attach_defaults, vFppuuuu)
GO(gtk_table_get_col_spacing, uFpu)
@@ -2864,7 +2890,7 @@ GO(gtk_table_get_default_row_spacing, uFp)
GO(gtk_table_get_homogeneous, iFp)
GO(gtk_table_get_row_spacing, uFpu)
GO(gtk_table_get_size, vFppp)
-GO(gtk_table_get_type, pFv)
+GO(gtk_table_get_type, LFv)
GO(gtk_table_new, pFuui)
GO(gtk_table_resize, vFpuu)
GO(gtk_table_set_col_spacing, vFpuu)
@@ -2872,8 +2898,8 @@ GO(gtk_table_set_col_spacings, vFpu)
GO(gtk_table_set_homogeneous, vFpi)
GO(gtk_table_set_row_spacing, vFpuu)
GO(gtk_table_set_row_spacings, vFpu)
-GO(gtk_target_entry_get_type, pFv)
-GO(gtk_target_flags_get_type, pFv)
+GO(gtk_target_entry_get_type, LFv)
+GO(gtk_target_flags_get_type, LFv)
GO(gtk_target_list_add, vFppuu)
GO(gtk_target_list_add_image_targets, vFpui)
GO(gtk_target_list_add_rich_text_targets, vFpuip)
@@ -2881,7 +2907,7 @@ GO(gtk_target_list_add_table, vFppu)
GO(gtk_target_list_add_text_targets, vFpu)
GO(gtk_target_list_add_uri_targets, vFpu)
GO(gtk_target_list_find, iFppp)
-GO(gtk_target_list_get_type, pFv)
+GO(gtk_target_list_get_type, LFv)
GO(gtk_target_list_new, pFpu)
GO(gtk_target_list_ref, pFp)
GO(gtk_target_list_remove, vFpp)
@@ -2892,7 +2918,7 @@ GO(gtk_targets_include_text, iFpi)
GO(gtk_targets_include_uri, iFpi)
GO(gtk_target_table_free, vFpi)
GO(gtk_target_table_new_from_list, pFpp)
-GO(gtk_tearoff_menu_item_get_type, pFv)
+GO(gtk_tearoff_menu_item_get_type, LFv)
GO(gtk_tearoff_menu_item_new, pFv)
GO(gtk_test_create_simple_window, pFpp)
//GO(gtk_test_create_widget,
@@ -2913,7 +2939,7 @@ GO(gtk_test_widget_send_key, iFpuu)
GO(gtk_text_anchored_child_set_layout, vFpp)
GO(gtk_text_attributes_copy, pFp)
GO(gtk_text_attributes_copy_values, vFpp)
-GO(gtk_text_attributes_get_type, pFv)
+GO(gtk_text_attributes_get_type, LFv)
GO(gtk_text_attributes_new, pFv)
GO(gtk_text_attributes_ref, pFp)
GO(gtk_text_attributes_unref, vFp)
@@ -2962,7 +2988,7 @@ GO(gtk_text_buffer_get_slice, pFpppi)
GO(gtk_text_buffer_get_start_iter, vFpp)
GO(gtk_text_buffer_get_tag_table, pFp)
GO(gtk_text_buffer_get_text, pFpppi)
-GO(gtk_text_buffer_get_type, pFv)
+GO(gtk_text_buffer_get_type, LFv)
GO(gtk_text_buffer_insert, vFpppi)
GO(gtk_text_buffer_insert_at_cursor, vFppi)
GO(gtk_text_buffer_insert_child_anchor, vFppp)
@@ -2990,23 +3016,23 @@ GO(gtk_text_buffer_select_range, vFppp)
GO(gtk_text_buffer_serialize, pFpppppp)
GO(gtk_text_buffer_set_modified, vFpi)
GO(gtk_text_buffer_set_text, vFppi)
-GO(gtk_text_buffer_target_info_get_type, pFv)
+GO(gtk_text_buffer_target_info_get_type, LFv)
GO(gtk_text_buffer_unregister_deserialize_format, vFpp)
GO(gtk_text_buffer_unregister_serialize_format, vFpp)
GO(gtk_text_byte_begins_utf8_char, iFp)
GO(gtk_text_child_anchor_get_deleted, iFp)
-GO(gtk_text_child_anchor_get_type, pFv)
+GO(gtk_text_child_anchor_get_type, LFv)
GO(gtk_text_child_anchor_get_widgets, pFp)
GO(gtk_text_child_anchor_new, pFv)
GO(gtk_text_child_anchor_queue_resize, vFpp)
GO(gtk_text_child_anchor_register_child, vFppp)
GO(gtk_text_child_anchor_unregister_child, vFpp)
-GO(gtk_text_direction_get_type, pFv)
+GO(gtk_text_direction_get_type, LFv)
GO(gtk_text_forward_delete, iFpu)
GO(gtk_text_freeze, vFp)
GO(gtk_text_get_length, uFp)
GO(gtk_text_get_point, uFp)
-GO(gtk_text_get_type, pFv)
+GO(gtk_text_get_type, LFv)
GO(gtk_text_insert, vFpppppi)
GO(gtk_text_iter_backward_char, iFp)
GO(gtk_text_iter_backward_chars, iFpi)
@@ -3076,7 +3102,7 @@ GO(gtk_text_iter_get_slice, pFpp)
GO(gtk_text_iter_get_tags, pFp)
GO(gtk_text_iter_get_text, pFpp)
GO(gtk_text_iter_get_toggled_tags, pFpi)
-GO(gtk_text_iter_get_type, pFv)
+GO(gtk_text_iter_get_type, LFv)
GO(gtk_text_iter_get_visible_line_index, iFp)
GO(gtk_text_iter_get_visible_line_offset, iFp)
GO(gtk_text_iter_get_visible_slice, pFpp)
@@ -3118,7 +3144,7 @@ GO(gtk_text_iter_toggles_tag, iFpp)
//GO(gtk_text_layout_get_lines,
//GO(gtk_text_layout_get_line_yrange,
//GO(gtk_text_layout_get_size,
-GO(gtk_text_layout_get_type, pFv)
+GO(gtk_text_layout_get_type, LFv)
//GO(gtk_text_layout_invalidate,
//GO(gtk_text_layout_invalidate_cursors,
//GO(gtk_text_layout_is_valid,
@@ -3149,12 +3175,12 @@ GO(gtk_text_mark_get_buffer, pFp)
GO(gtk_text_mark_get_deleted, iFp)
GO(gtk_text_mark_get_left_gravity, iFp)
GO(gtk_text_mark_get_name, pFp)
-GO(gtk_text_mark_get_type, pFv)
+GO(gtk_text_mark_get_type, LFv)
GO(gtk_text_mark_get_visible, iFp)
GO(gtk_text_mark_new, pFpi)
GO(gtk_text_mark_set_visible, vFpi)
GO(gtk_text_new, pFpp)
-GO(gtk_text_search_flags_get_type, pFv)
+GO(gtk_text_search_flags_get_type, LFv)
GO(gtk_text_set_adjustments, vFppp)
GO(gtk_text_set_editable, vFpi)
GO(gtk_text_set_line_wrap, vFpi)
@@ -3162,13 +3188,13 @@ GO(gtk_text_set_point, vFpu)
GO(gtk_text_set_word_wrap, vFpi)
GO(gtk_text_tag_event, iFpppp)
GO(gtk_text_tag_get_priority, iFp)
-GO(gtk_text_tag_get_type, pFv)
+GO(gtk_text_tag_get_type, LFv)
GO(gtk_text_tag_new, pFp)
GO(gtk_text_tag_set_priority, vFpi)
GO(gtk_text_tag_table_add, iFpp)
//GOM(gtk_text_tag_table_foreach, vFEpBp)
GO(gtk_text_tag_table_get_size, iFp)
-GO(gtk_text_tag_table_get_type, pFv)
+GO(gtk_text_tag_table_get_type, LFv)
GO(gtk_text_tag_table_lookup, pFpp)
GO(gtk_text_tag_table_new, pFv)
GO(gtk_text_tag_table_remove, vFpp)
@@ -3201,7 +3227,7 @@ GO(gtk_text_view_get_pixels_below_lines, iFp)
GO(gtk_text_view_get_pixels_inside_wrap, iFp)
GO(gtk_text_view_get_right_margin, iFp)
GO(gtk_text_view_get_tabs, pFp)
-GO(gtk_text_view_get_type, pFv)
+GO(gtk_text_view_get_type, LFv)
GO(gtk_text_view_get_vadjustment, pFp)
GO(gtk_text_view_get_visible_rect, vFpp)
GO(gtk_text_view_get_window, pFpu)
@@ -3235,14 +3261,14 @@ GO(gtk_text_view_set_tabs, vFpp)
GO(gtk_text_view_set_wrap_mode, vFpu)
GO(gtk_text_view_starts_display_line, iFpp)
GO(gtk_text_view_window_to_buffer_coords, vFpuiipp)
-GO(gtk_text_window_type_get_type, pFv)
+GO(gtk_text_window_type_get_type, LFv)
//GO(gtk_theme_engine_create_rc_style,
//GO(gtk_theme_engine_get,
-GO(gtk_theme_engine_get_type, pFv)
+GO(gtk_theme_engine_get_type, LFv)
GOM(gtk_timeout_add, uFEupp)
//GOM(gtk_timeout_add_full, uFuBppB)
GO(gtk_timeout_remove, vFu)
-GO(gtk_tips_query_get_type, pFv)
+GO(gtk_tips_query_get_type, LFv)
//GO(gtk_tips_query_new,
//GO(gtk_tips_query_set_caller,
//GO(gtk_tips_query_set_labels,
@@ -3250,7 +3276,7 @@ GO(gtk_tips_query_get_type, pFv)
//GO(gtk_tips_query_stop_query,
//GO(gtk_toggle_action_get_active,
GO(gtk_toggle_action_get_draw_as_radio, iFp)
-GO(gtk_toggle_action_get_type, pFv)
+GO(gtk_toggle_action_get_type, LFv)
GO(gtk_toggle_action_new, pFpppp)
//GO(gtk_toggle_action_set_active,
//GO(gtk_toggle_action_set_draw_as_radio,
@@ -3258,7 +3284,7 @@ GO(gtk_toggle_action_toggled, vFp)
GO(gtk_toggle_button_get_active, iFp)
GO(gtk_toggle_button_get_inconsistent, iFp)
GO(gtk_toggle_button_get_mode, iFp)
-GO(gtk_toggle_button_get_type, pFv)
+GO(gtk_toggle_button_get_type, LFv)
GO(gtk_toggle_button_new, pFv)
GO(gtk_toggle_button_new_with_label, pFp)
GO(gtk_toggle_button_new_with_mnemonic, pFp)
@@ -3267,7 +3293,7 @@ GO(gtk_toggle_button_set_inconsistent, vFpi)
GO(gtk_toggle_button_set_mode, vFpi)
GO(gtk_toggle_button_toggled, vFp)
GO(gtk_toggle_tool_button_get_active, iFp)
-GO(gtk_toggle_tool_button_get_type, pFv)
+GO(gtk_toggle_tool_button_get_type, LFv)
GO(gtk_toggle_tool_button_new, pFv)
GO(gtk_toggle_tool_button_new_from_stock, pFp)
GO(gtk_toggle_tool_button_set_active, vFpi)
@@ -3275,7 +3301,7 @@ GOM(gtk_toolbar_append_element, pFEpippppppp)
GOM(gtk_toolbar_append_item, pFEppppppp)
GO(gtk_toolbar_append_space, vFp)
GO(gtk_toolbar_append_widget, vFpppp)
-GO(gtk_toolbar_child_type_get_type, pFv)
+GO(gtk_toolbar_child_type_get_type, LFv)
GO(gtk_toolbar_get_drop_index, iFpii)
GO(gtk_toolbar_get_icon_size, uFp)
GO(gtk_toolbar_get_item_index, iFpp)
@@ -3286,7 +3312,7 @@ GO(gtk_toolbar_get_relief_style, uFp)
GO(gtk_toolbar_get_show_arrow, iFp)
GO(gtk_toolbar_get_style, uFp)
GO(gtk_toolbar_get_tooltips, iFp)
-GO(gtk_toolbar_get_type, pFv)
+GO(gtk_toolbar_get_type, LFv)
GO(gtk_toolbar_insert, vFppi)
GOM(gtk_toolbar_insert_element, pFEpipppppppi)
GOM(gtk_toolbar_insert_item, pFEpppppppi)
@@ -3305,8 +3331,8 @@ GO(gtk_toolbar_set_orientation, vFpi)
GO(gtk_toolbar_set_show_arrow, vFpi)
GO(gtk_toolbar_set_style, vFpu)
GO(gtk_toolbar_set_tooltips, vFpi)
-GO(gtk_toolbar_space_style_get_type, pFv)
-GO(gtk_toolbar_style_get_type, pFv)
+GO(gtk_toolbar_space_style_get_type, LFv)
+GO(gtk_toolbar_style_get_type, LFv)
GO(gtk_toolbar_unset_icon_size, vFp)
GO(gtk_toolbar_unset_style, vFp)
GO(gtk_tool_button_get_icon_name, pFp)
@@ -3314,7 +3340,7 @@ GO(gtk_tool_button_get_icon_widget, pFp)
GO(gtk_tool_button_get_label, pFp)
GO(gtk_tool_button_get_label_widget, pFp)
GO(gtk_tool_button_get_stock_id, pFp)
-GO(gtk_tool_button_get_type, pFv)
+GO(gtk_tool_button_get_type, LFv)
GO(gtk_tool_button_get_use_underline, iFp)
GO(gtk_tool_button_new, pFpp)
GO(gtk_tool_button_new_from_stock, pFp)
@@ -3336,7 +3362,7 @@ GO(gtk_tool_item_get_text_alignment, fFp)
GO(gtk_tool_item_get_text_orientation, uFp)
GO(gtk_tool_item_get_text_size_group, pFp)
GO(gtk_tool_item_get_toolbar_style, uFp)
-GO(gtk_tool_item_get_type, pFv)
+GO(gtk_tool_item_get_type, LFv)
//GO(gtk_tool_item_get_use_drag_window,
//GO(gtk_tool_item_get_visible_horizontal,
//GO(gtk_tool_item_get_visible_vertical,
@@ -3349,7 +3375,7 @@ GO(gtk_tool_item_group_get_label, pFp)
GO(gtk_tool_item_group_get_label_widget, pFp)
GO(gtk_tool_item_group_get_n_items, uFp)
GO(gtk_tool_item_group_get_nth_item, pFpu)
-GO(gtk_tool_item_group_get_type, pFv)
+GO(gtk_tool_item_group_get_type, LFv)
//GO(gtk_tool_item_group_insert,
//GO(gtk_tool_item_group_new,
GO(gtk_tool_item_group_set_collapsed, vFpi)
@@ -3373,7 +3399,7 @@ GO(gtk_tool_item_set_tooltip_markup, vFpp)
//GO(gtk_tool_item_set_visible_vertical,
//GO(gtk_tool_item_toolbar_reconfigured,
GO(gtk_tool_palette_add_drag_dest, vFppuuu)
-GO(gtk_tool_palette_drag_targets_get_type, pFv)
+GO(gtk_tool_palette_drag_targets_get_type, LFv)
GO(gtk_tool_palette_get_drag_item, pFpp)
GO(gtk_tool_palette_get_drag_target_group, pFv)
//GO(gtk_tool_palette_get_drag_target_item,
@@ -3385,7 +3411,7 @@ GO(gtk_tool_palette_get_group_position, iFpp)
//GO(gtk_tool_palette_get_hadjustment,
GO(gtk_tool_palette_get_icon_size, uFp)
GO(gtk_tool_palette_get_style, uFp)
-GO(gtk_tool_palette_get_type, pFv)
+GO(gtk_tool_palette_get_type, LFv)
GO(gtk_tool_palette_get_vadjustment, pFp)
//GO(gtk_tool_palette_new,
GO(gtk_tool_palette_set_drag_source, vFpu)
@@ -3404,9 +3430,9 @@ GO(gtk_tool_shell_get_style, uFp)
GO(gtk_tool_shell_get_text_alignment, fFp)
GO(gtk_tool_shell_get_text_orientation, uFp)
GO(gtk_tool_shell_get_text_size_group, pFp)
-GO(gtk_tool_shell_get_type, pFv)
+GO(gtk_tool_shell_get_type, LFv)
//GO(gtk_tool_shell_rebuild_menu,
-GO(gtk_tooltip_get_type, pFv)
+GO(gtk_tooltip_get_type, LFv)
GO(gtk_tooltips_data_get, pFp)
GO(gtk_tooltips_disable, vFp)
GO(gtk_tooltips_enable, vFp)
@@ -3420,29 +3446,29 @@ GO(gtk_tooltip_set_text, vFpp)
GO(gtk_tooltip_set_tip_area, vFpp)
GO(gtk_tooltips_force_window, vFp)
GO(gtk_tooltips_get_info_from_tip_window, iFppp)
-GO(gtk_tooltips_get_type, pFv)
+GO(gtk_tooltips_get_type, LFv)
GO(gtk_tooltips_new, pFv)
GO(gtk_tooltips_set_delay, vFpu)
GO(gtk_tooltips_set_tip, vFpppp)
GO(gtk_tooltip_trigger_tooltip_query, vFp)
-GO(gtk_tray_icon_get_type, pFv)
+GO(gtk_tray_icon_get_type, LFv)
//GO(gtk_tree_append,
//GO(gtk_tree_child_position,
//GO(gtk_tree_clear_items,
//GO(gtk_tree_drag_dest_drag_data_received,
-GO(gtk_tree_drag_dest_get_type, pFv)
+GO(gtk_tree_drag_dest_get_type, LFv)
GO(gtk_tree_drag_dest_row_drop_possible, iFppp)
GO(gtk_tree_drag_source_drag_data_delete, iFpp)
GO(gtk_tree_drag_source_drag_data_get, iFppp)
-GO(gtk_tree_drag_source_get_type, pFv)
+GO(gtk_tree_drag_source_get_type, LFv)
//GO(gtk_tree_drag_source_row_draggable,
GO(gtk_tree_get_row_drag_data, iFppp)
-GO(gtk_tree_get_type, pFv)
+GO(gtk_tree_get_type, LFv)
//GO(gtk_tree_insert,
//GO(gtk_tree_item_collapse,
//GO(gtk_tree_item_deselect,
//GO(gtk_tree_item_expand,
-GO(gtk_tree_item_get_type, pFv)
+GO(gtk_tree_item_get_type, LFv)
//GO(gtk_tree_item_new,
//GO(gtk_tree_item_new_with_label,
//GO(gtk_tree_item_remove_subtree,
@@ -3450,20 +3476,20 @@ GO(gtk_tree_item_get_type, pFv)
//GO(gtk_tree_item_set_subtree,
GO(gtk_tree_iter_copy, pFp)
GO(gtk_tree_iter_free, vFp)
-GO(gtk_tree_iter_get_type, pFv)
+GO(gtk_tree_iter_get_type, LFv)
//GO(gtk_tree_model_filter_clear_cache,
GO(gtk_tree_model_filter_convert_child_iter_to_iter, iFppp)
//GO(gtk_tree_model_filter_convert_child_path_to_path,
GO(gtk_tree_model_filter_convert_iter_to_child_iter, vFppp)
GO(gtk_tree_model_filter_convert_path_to_child_path, pFpp)
GO(gtk_tree_model_filter_get_model, pFp)
-GO(gtk_tree_model_filter_get_type, pFv)
+GO(gtk_tree_model_filter_get_type, LFv)
GO(gtk_tree_model_filter_new, pFpp)
//GO(gtk_tree_model_filter_refilter,
//GO(gtk_tree_model_filter_set_modify_func,
GO(gtk_tree_model_filter_set_visible_column, vFpi)
//GO(gtk_tree_model_filter_set_visible_func,
-GO(gtk_tree_model_flags_get_type, pFv)
+GO(gtk_tree_model_flags_get_type, LFv)
//GOM(gtk_tree_model_foreach, vFEpBp)
//GO2(gtk_tree_model_get, vFppV, gtk_tree_model_get_valist)
GO(gtk_tree_model_get_column_type, LFpi)
@@ -3474,7 +3500,7 @@ GO(gtk_tree_model_get_iter_from_string, iFppp)
GO(gtk_tree_model_get_n_columns, iFp)
GO(gtk_tree_model_get_path, pFpp)
GO(gtk_tree_model_get_string_from_iter, pFpp)
-GO(gtk_tree_model_get_type, pFv)
+GO(gtk_tree_model_get_type, LFv)
//GO(gtk_tree_model_get_valist, vFppp)
GO(gtk_tree_model_get_value, vFppip)
GO(gtk_tree_model_iter_children, iFppp)
@@ -3495,7 +3521,7 @@ GO(gtk_tree_model_sort_convert_child_iter_to_iter, iFppp)
GO(gtk_tree_model_sort_convert_iter_to_child_iter, vFppp)
GO(gtk_tree_model_sort_convert_path_to_child_path, pFpp)
GO(gtk_tree_model_sort_get_model, pFp)
-GO(gtk_tree_model_sort_get_type, pFv)
+GO(gtk_tree_model_sort_get_type, LFv)
GO(gtk_tree_model_sort_iter_is_valid, iFpp)
GO(gtk_tree_model_sort_new_with_model, pFp)
//GO(gtk_tree_model_sort_reset_default_sort_func,
@@ -3509,7 +3535,7 @@ GO(gtk_tree_path_free, vFp)
GO(gtk_tree_path_get_depth, iFp)
GO(gtk_tree_path_get_indices, pFp)
GO(gtk_tree_path_get_indices_with_depth, pFpp)
-GO(gtk_tree_path_get_type, pFv)
+GO(gtk_tree_path_get_type, LFv)
GO(gtk_tree_path_is_ancestor, iFpp)
GO(gtk_tree_path_is_descendant, iFpp)
GO(gtk_tree_path_new, pFv)
@@ -3529,7 +3555,7 @@ GO(gtk_tree_row_reference_deleted, vFpp)
GO(gtk_tree_row_reference_free, vFp)
GO(gtk_tree_row_reference_get_model, pFp)
GO(gtk_tree_row_reference_get_path, pFp)
-GO(gtk_tree_row_reference_get_type, pFv)
+GO(gtk_tree_row_reference_get_type, LFv)
GO(gtk_tree_row_reference_inserted, vFpp)
GO(gtk_tree_row_reference_new, pFpp)
GO(gtk_tree_row_reference_new_proxy, pFppp)
@@ -3542,7 +3568,7 @@ GO(gtk_tree_selection_get_selected, iFppp)
GO(gtk_tree_selection_get_selected_rows, pFpp)
//GOM(gtk_tree_selection_get_select_function, BFEp)
GO(gtk_tree_selection_get_tree_view, pFp)
-GO(gtk_tree_selection_get_type, pFv)
+GO(gtk_tree_selection_get_type, LFv)
//GOM(gtk_tree_selection_get_user_data, pFEp)
GO(gtk_tree_selection_iter_is_selected, iFpp)
GO(gtk_tree_selection_path_is_selected, iFpp)
@@ -3563,7 +3589,7 @@ GO(gtk_tree_set_row_drag_data, iFppp)
//GO(gtk_tree_set_view_lines,
//GO(gtk_tree_set_view_mode,
GO(gtk_tree_sortable_get_sort_column_id, iFppp)
-GO(gtk_tree_sortable_get_type, pFv)
+GO(gtk_tree_sortable_get_type, LFv)
GO(gtk_tree_sortable_has_default_sort_func, iFp)
GOM(gtk_tree_sortable_set_default_sort_func, vFEpppp)
GO(gtk_tree_sortable_set_sort_column_id, vFpiu)
@@ -3571,7 +3597,7 @@ GOM(gtk_tree_sortable_set_sort_func, vFEpippp)
GO(gtk_tree_sortable_sort_column_changed, vFp)
GO(gtk_tree_store_append, vFppp)
GO(gtk_tree_store_clear, vFp)
-GO(gtk_tree_store_get_type, pFv)
+GO(gtk_tree_store_get_type, LFv)
GO(gtk_tree_store_insert, vFpppi)
GO(gtk_tree_store_insert_after, vFpppp)
//GO(gtk_tree_store_insert_before,
@@ -3608,6 +3634,7 @@ GO(gtk_tree_view_column_clear_attributes, vFpp)
GO(gtk_tree_view_column_clicked, vFp)
GO(gtk_tree_view_column_focus_cell, vFpp)
GO(gtk_tree_view_column_get_alignment, fFp)
+GO(gtk_tree_view_column_get_button, pFp)
GO(gtk_tree_view_column_get_cell_renderers, pFp)
GO(gtk_tree_view_column_get_clickable, iFp)
GO(gtk_tree_view_column_get_expand, iFp)
@@ -3623,7 +3650,7 @@ GO(gtk_tree_view_column_get_sort_order, uFp)
GO(gtk_tree_view_column_get_spacing, iFp)
GO(gtk_tree_view_column_get_title, pFp)
GO(gtk_tree_view_column_get_tree_view, pFp)
-GO(gtk_tree_view_column_get_type, pFv)
+GO(gtk_tree_view_column_get_type, LFv)
GO(gtk_tree_view_column_get_visible, iFp)
GO(gtk_tree_view_column_get_widget, pFp)
GO(gtk_tree_view_column_get_width, iFp)
@@ -3651,7 +3678,7 @@ GO(gtk_tree_view_column_set_spacing, vFpi)
GO(gtk_tree_view_column_set_title, vFpp)
GO(gtk_tree_view_column_set_visible, vFpi)
GO(gtk_tree_view_column_set_widget, vFpp)
-GO(gtk_tree_view_column_sizing_get_type, pFv)
+GO(gtk_tree_view_column_sizing_get_type, LFv)
GO(gtk_tree_view_convert_bin_window_to_tree_coords, vFpiipp)
GO(gtk_tree_view_convert_bin_window_to_widget_coords, vFpiipp)
GO(gtk_tree_view_convert_tree_to_bin_window_coords, vFpiipp)
@@ -3659,7 +3686,7 @@ GO(gtk_tree_view_convert_tree_to_widget_coords, vFpiipp)
GO(gtk_tree_view_convert_widget_to_bin_window_coords, vFpiipp)
GO(gtk_tree_view_convert_widget_to_tree_coords, vFpiipp)
GO(gtk_tree_view_create_row_drag_icon, pFpp)
-GO(gtk_tree_view_drop_position_get_type, pFv)
+GO(gtk_tree_view_drop_position_get_type, LFv)
GO(gtk_tree_view_enable_model_drag_dest, vFppiu)
GO(gtk_tree_view_enable_model_drag_source, vFpupiu)
GO(gtk_tree_view_expand_all, vFp)
@@ -3698,17 +3725,17 @@ GO(gtk_tree_view_get_selection, pFp)
GO(gtk_tree_view_get_show_expanders, iFp)
GO(gtk_tree_view_get_tooltip_column, iFp)
GO(gtk_tree_view_get_tooltip_context, iFpppippp)
-GO(gtk_tree_view_get_type, pFv)
+GO(gtk_tree_view_get_type, LFv)
GO(gtk_tree_view_get_vadjustment, pFp)
GO(gtk_tree_view_get_visible_range, iFppp)
GO(gtk_tree_view_get_visible_rect, vFpp)
-GO(gtk_tree_view_grid_lines_get_type, pFv)
+GO(gtk_tree_view_grid_lines_get_type, LFv)
GO(gtk_tree_view_insert_column, iFppi)
GO(gtk_tree_view_insert_column_with_attributes, iFpipppppppppppp) //vaarg
//GOM(gtk_tree_view_insert_column_with_data_func, iFpippBpB)
GO(gtk_tree_view_is_rubber_banding_active, iFp)
//GOM(gtk_tree_view_map_expanded_rows, vFEpBp)
-GO(gtk_tree_view_mode_get_type, pFv)
+GO(gtk_tree_view_mode_get_type, LFv)
GO(gtk_tree_view_move_column_after, vFppp)
GO(gtk_tree_view_new, pFv)
GO(gtk_tree_view_new_with_model, pFp)
@@ -3769,47 +3796,47 @@ GO(gtk_ui_manager_get_action, pFpp)
GO(gtk_ui_manager_get_action_groups, pFp)
GO(gtk_ui_manager_get_add_tearoffs, iFp)
GO(gtk_ui_manager_get_toplevels, pFpu)
-GO(gtk_ui_manager_get_type, pFv)
+GO(gtk_ui_manager_get_type, LFv)
GO(gtk_ui_manager_get_ui, pFp)
GO(gtk_ui_manager_get_widget, pFpp)
GO(gtk_ui_manager_insert_action_group, vFppi)
-GO(gtk_ui_manager_item_type_get_type, pFv)
+GO(gtk_ui_manager_item_type_get_type, LFv)
GO(gtk_ui_manager_new, pFv)
GO(gtk_ui_manager_new_merge_id, uFp)
GO(gtk_ui_manager_remove_action_group, vFpp)
GO(gtk_ui_manager_remove_ui, vFpu)
GO(gtk_ui_manager_set_add_tearoffs, vFpi)
-GO(gtk_unit_get_type, pFv)
-GO(gtk_update_type_get_type, pFv)
-GO(gtk_vbox_get_type, pFv)
+GO(gtk_unit_get_type, LFv)
+GO(gtk_update_type_get_type, LFv)
+GO(gtk_vbox_get_type, LFv)
GO(gtk_vbox_new, pFii)
//GO(gtk_vbutton_box_get_layout_default,
//GO(gtk_vbutton_box_get_spacing_default,
-GO(gtk_vbutton_box_get_type, pFv)
+GO(gtk_vbutton_box_get_type, LFv)
//GO(gtk_vbutton_box_new,
//GO(gtk_vbutton_box_set_layout_default,
//GO(gtk_vbutton_box_set_spacing_default,
//GO(gtk_viewport_get_bin_window,
//GO(gtk_viewport_get_hadjustment,
GO(gtk_viewport_get_shadow_type, uFp)
-GO(gtk_viewport_get_type, pFv)
+GO(gtk_viewport_get_type, LFv)
GO(gtk_viewport_get_vadjustment, pFp)
GO(gtk_viewport_get_view_window, pFp)
GO(gtk_viewport_new, pFpp)
//GO(gtk_viewport_set_hadjustment,
GO(gtk_viewport_set_shadow_type, vFpu)
GO(gtk_viewport_set_vadjustment, vFpp)
-GO(gtk_visibility_get_type, pFv)
-GO(gtk_volume_button_get_type, pFv)
+GO(gtk_visibility_get_type, LFv)
+GO(gtk_volume_button_get_type, LFv)
GO(gtk_volume_button_new, pFv)
-GO(gtk_vpaned_get_type, pFv)
+GO(gtk_vpaned_get_type, LFv)
GO(gtk_vpaned_new, pFv)
-GO(gtk_vruler_get_type, pFv)
+GO(gtk_vruler_get_type, LFv)
GO(gtk_vruler_new, pFv)
-GO(gtk_vscale_get_type, pFv)
+GO(gtk_vscale_get_type, LFv)
GO(gtk_vscale_new, pFp)
GO(gtk_vscale_new_with_range, pFddd)
-GO(gtk_vscrollbar_get_type, pFv)
+GO(gtk_vscrollbar_get_type, LFv)
GO(gtk_vscrollbar_new, pFp)
GO(gtk_vseparator_get_type, LFv)
GO(gtk_vseparator_new, pFv)
@@ -3840,19 +3867,20 @@ GO(gtk_widget_draw, vFpp)
GO(gtk_widget_ensure_style, vFp)
GO(gtk_widget_error_bell, vFp)
GO(gtk_widget_event, iFpp)
-GO(gtk_widget_flags_get_type, pFv)
+GO(gtk_widget_flags_get_type, LFv)
GO(gtk_widget_freeze_child_notify, vFp)
GO(gtk_widget_get_accessible, pFp)
GO(gtk_widget_get_action, pFp)
GO(gtk_widget_get_allocation, vFpp)
GO(gtk_widget_get_allocated_width, iFp)
GO(gtk_widget_get_allocated_height, iFp)
-GO(gtk_widget_get_ancestor, pFpi)
+GO(gtk_widget_get_ancestor, pFpL)
GO(gtk_widget_get_app_paintable, iFp)
GO(gtk_widget_get_can_default, iFp)
GO(gtk_widget_get_can_focus, iFp)
GO(gtk_widget_get_child_requisition, vFpp)
GO(gtk_widget_get_child_visible, iFp)
+GO(gtk_widget_get_clip, vFpp)
GO(gtk_widget_get_clipboard, pFpp)
GO(gtk_widget_get_colormap, pFp)
GO(gtk_widget_get_composite_name, pFp)
@@ -3911,7 +3939,7 @@ GO(gtk_widget_get_tooltip_markup, pFp)
GO(gtk_widget_get_tooltip_text, pFp)
GO(gtk_widget_get_tooltip_window, pFp)
GO(gtk_widget_get_toplevel, pFp)
-GO(gtk_widget_get_type, pFv)
+GO(gtk_widget_get_type, LFv)
GO(gtk_widget_get_valign, iFp)
GO(gtk_widget_get_valign_with_baseline, uFp)
GO(gtk_widget_get_vexpand, iFp)
@@ -3926,7 +3954,7 @@ GO(gtk_widget_has_focus, iFp)
GO(gtk_widget_has_grab, iFp)
GO(gtk_widget_has_rc_style, iFp)
GO(gtk_widget_has_screen, iFp)
-GO(gtk_widget_help_type_get_type, pFv)
+GO(gtk_widget_help_type_get_type, LFv)
GO(gtk_widget_hide, vFp)
GO(gtk_widget_hide_all, vFp)
GO(gtk_widget_hide_on_delete, iFp)
@@ -4021,6 +4049,7 @@ GO(gtk_widget_set_app_paintable, vFpi)
GO(gtk_widget_set_can_default, vFpi)
GO(gtk_widget_set_can_focus, vFpi)
GO(gtk_widget_set_child_visible, vFpi)
+GO(gtk_widget_set_clip, vFpp)
GO(gtk_widget_set_colormap, vFpp)
GO(gtk_widget_set_composite_name, vFpp)
GO(gtk_widget_set_css_classes, vFpp)
@@ -4075,7 +4104,7 @@ GO(gtk_widget_show_now, vFp)
GO(gtk_widget_size_allocate, vFpppuii)
GO(gtk_widget_size_request, vFpp)
GO(gtk_widget_style_attach, vFp)
-//GO2(gtk_widget_style_get, vFppV, gtk_widget_style_get_valist)
+GOM(gtk_widget_style_get, vFEppV)
GO(gtk_widget_style_get_property, vFppp)
//GO(gtk_widget_style_get_valist, vFppp)
GO(gtk_widget_thaw_child_notify, vFp)
@@ -4098,6 +4127,7 @@ GO(gtk_window_deiconify, vFp)
GO(gtk_window_destroy, vFp)
GO(gtk_window_fullscreen, vFp)
GO(gtk_window_get_accept_focus, iFp)
+GO(gdk_window_get_clip_region, pFp)
GO(gtk_window_get_decorated, iFp)
GO(gtk_window_get_default_icon_list, pFv)
GO(gtk_window_get_default_icon_name, pFv)
@@ -4111,6 +4141,7 @@ GO(gtk_window_get_frame_dimensions, vFppppp)
GO(gtk_window_get_gravity, uFp)
GO(gtk_window_get_group, pFp)
GO(gtk_window_get_has_frame, iFp)
+GO(gtk_window_get_has_resize_grip, iFp)
GO(gtk_window_get_icon, pFp)
GO(gtk_window_get_icon_list, pFp)
GO(gtk_window_get_icon_name, pFp)
@@ -4121,19 +4152,20 @@ GO(gtk_window_get_opacity, dFp)
GO(gtk_window_get_position, vFppp)
GO(gtk_window_get_resizable, iFp)
GO(gtk_window_get_role, pFp)
+GO(gdk_window_get_scale_factor, iFp)
GO(gtk_window_get_screen, pFp)
GO(gtk_window_get_size, vFppp)
GO(gtk_window_get_skip_pager_hint, iFp)
GO(gtk_window_get_skip_taskbar_hint, iFp)
GO(gtk_window_get_title, pFp)
GO(gtk_window_get_transient_for, pFp)
-GO(gtk_window_get_type, pFv)
+GO(gtk_window_get_type, LFv)
GO(gtk_window_get_type_hint, uFp)
GO(gtk_window_get_urgency_hint, iFp)
GO(gtk_window_get_window_type, uFp)
GO(gtk_window_group_add_window, vFpp)
GO(gtk_window_group_get_current_grab, pFp)
-GO(gtk_window_group_get_type, pFv)
+GO(gtk_window_group_get_type, LFv)
GO(gtk_window_group_list_windows, pFp)
GO(gtk_window_group_new, pFv)
GO(gtk_window_group_remove_window, vFpp)
@@ -4147,7 +4179,7 @@ GO(gtk_window_mnemonic_activate, iFpuu)
GO(gtk_window_move, vFpii)
GO(gtk_window_new, pFu)
GO(gtk_window_parse_geometry, iFpp)
-GO(gtk_window_position_get_type, pFv)
+GO(gtk_window_position_get_type, LFv)
GO(gtk_window_present, vFp)
GO(gtk_window_present_with_time, vFpu)
GO(gtk_window_propagate_key_event, iFpp)
@@ -4200,11 +4232,11 @@ GO(gtk_window_set_urgency_hint, vFpi)
GO(gtk_widget_set_visual, vFpp)
GO(gtk_window_set_wmclass, vFppp)
GO(gtk_window_stick, vFp)
-GO(gtk_window_type_get_type, pFv)
+GO(gtk_window_type_get_type, LFv)
GO(gtk_window_unfullscreen, vFp)
GO(gtk_window_unmaximize, vFp)
GO(gtk_window_unstick, vFp)
-GO(gtk_wrap_mode_get_type, pFv)
+GO(gtk_wrap_mode_get_type, LFv)
GO(gtk_gesture_long_press_get_type, LFv)
GO(gtk_gesture_single_get_type, LFv)
GO(gtk_gesture_get_type, LFv)
@@ -4215,3 +4247,5 @@ GO(gtk_stack_set_visible_child_name, vFpp)
GO(gtk_stack_get_visible_child_name, pFp)
GO(dummy_iFppdd, iFppdd) // for GtkEventController wrapping
+GO(dummy_iFppUup, iFppUup)
+GO(dummy_pFpLi, pFpLi) \ No newline at end of file
diff --git a/src/wrapped/wrappediconv.c b/src/wrapped/wrappediconv.c
new file mode 100644
index 0000000..dea2ff8
--- /dev/null
+++ b/src/wrapped/wrappediconv.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* iconvName = "libiconv.so";
+
+#define LIBNAME iconv
+
+#define CUSTOM_INIT \
+ setNeededLibs(lib, 1, "libc.so");
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappediconv_private.h b/src/wrapped/wrappediconv_private.h
new file mode 100644
index 0000000..a0ed8e1
--- /dev/null
+++ b/src/wrapped/wrappediconv_private.h
@@ -0,0 +1,4 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA) && defined(GOS))
+#error Meh...
+#endif
+
diff --git a/src/wrapped/wrappedicui18n66.c b/src/wrapped/wrappedicui18n66.c
new file mode 100644
index 0000000..9a5fd09
--- /dev/null
+++ b/src/wrapped/wrappedicui18n66.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+
+const char* icui18n66Name = "libicui18n.so.66";
+#define LIBNAME icui18n66
+
+#define CUSTOM_INIT \
+ SETALT(my66_); \
+ setNeededLibs(lib, 1, "libicuuc.so.66");
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedicui18n66_private.h b/src/wrapped/wrappedicui18n66_private.h
new file mode 100644
index 0000000..55afb6e
--- /dev/null
+++ b/src/wrapped/wrappedicui18n66_private.h
@@ -0,0 +1,100 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(ucal_add_66, vFpiip)
+GO(ucal_clear_66, vFp)
+GO(ucal_clearField_66, vFpi)
+GO(ucal_clone_66, pFpp)
+GO(ucal_close_66, vFp)
+GO(ucal_countAvailable_66, iFv)
+GO(ucal_equivalentTo_66, cFpp)
+GO(ucal_get_66, iFpip)
+GO(ucal_getAttribute_66, iFpi)
+GO(ucal_getAvailable_66, pFi)
+GO(ucal_getCanonicalTimeZoneID_66, iFpipipp)
+GO(ucal_getDayOfWeekType_66, iFpip)
+GO(ucal_getDefaultTimeZone_66, iFpip)
+GO(ucal_getDSTSavings_66, iFpp)
+GO(ucal_getFieldDifference_66, iFpdip)
+GO(ucal_getGregorianChange_66, dFpp)
+GO(ucal_getHostTimeZone_66, iFpip)
+GO(ucal_getKeywordValuesForLocale_66, pFppCp)
+GO(ucal_getLimit_66, iFpiip)
+GO(ucal_getLocaleByType_66, pFpip)
+GO(ucal_getMillis_66, dFpp)
+GO(ucal_getNow_66, dFv)
+GO(ucal_getTimeZoneDisplayName_66, iFpippip)
+GO(ucal_getTimeZoneID_66, iFppip)
+GO(ucal_getTimeZoneIDForWindowsID_66, iFpippip)
+GO(ucal_getTimeZoneOffsetFromLocal_66, vFpiippp)
+GO(ucal_getTimeZoneTransitionDate_66, cFpipp)
+GO(ucal_getType_66, pFpp)
+GO(ucal_getTZDataVersion_66, pFp)
+GO(ucal_getWeekendTransition_66, iFpip)
+GO(ucal_getWindowsTimeZoneID_66, iFpipip)
+GO(ucal_inDaylightTime_66, cFpp)
+GO(ucal_isSet_66, cFpi)
+GO(ucal_isWeekend_66, cFpdp)
+GO(ucal_open_66, pFpipip)
+GO(ucal_openCountryTimeZones_66, pFpp)
+GO(ucal_openTimeZoneIDEnumeration_66, pFippp)
+GO(ucal_openTimeZones_66, pFp)
+GO(ucal_roll_66, vFpiip)
+GO(ucal_set_66, vFpii)
+GO(ucal_setAttribute_66, vFpii)
+GO(ucal_setDate_66, vFpiiip)
+GO(ucal_setDateTime_66, vFpiiiiiip)
+GO(ucal_setDefaultTimeZone_66, vFpp)
+GO(ucal_setGregorianChange_66, vFpdp)
+GO(ucal_setMillis_66, vFpdp)
+GO(ucal_setTimeZone_66, vFppip)
+
+GO(ucol_clone_66, pFpp)
+GO(ucol_close_66, vFp)
+GO(ucol_closeElements_66, vFp)
+GO(ucol_setMaxVariable_66, vFpip)
+GO(ucol_getOffset_66, iFp)
+GO(ucol_getRules_66, pFpp)
+GO(ucol_getSortKey_66, iFppipi)
+GO(ucol_getStrength_66, iFp)
+GO(ucol_getVersion_66, vFpp)
+GO(ucol_next_66, iFpp)
+GO(ucol_previous_66, iFpp)
+GO(ucol_open_66, pFpp)
+GO(ucol_openElements_66, pFppip)
+GO(ucol_openRules_66, pFpiiipp)
+GO(ucol_safeClone_66, pFpppp)
+GO(ucol_setAttribute_66, vFpiip)
+GO(ucol_setVariableTop_66, uFppip)
+GO(ucol_strcoll_66, iFppipi)
+
+GO(udat_close_66, vFp)
+GO(udat_countSymbols_66, iFpi)
+GO(udat_getSymbols_66, iFpiipip)
+GO(udat_format_66, iFpdpipp)
+GO(udat_open_66, pFiippipip)
+GO(udat_setCalendar_66, vFpp)
+GO(udat_toPattern_66, iFpCpip)
+
+GO(unum_close_66, vFp)
+GO(unum_getAttribute_66, iFpi)
+GO(unum_getSymbol_66, iFpipip)
+GO(unum_open_66, pFipippp)
+GO(unum_toPattern_66, iFpCpip)
+
+GO(udatpg_close_66, vFp)
+GO(udatpg_getBestPattern_66, iFppipip)
+GO(udatpg_open_66, pFpp)
+
+GO(ulocdata_getCLDRVersion_66, vFpp)
+GO(ulocdata_getMeasurementSystem_66, iFpp)
+
+GO(usearch_close_66, vFp)
+GO(usearch_first_66, iFpp)
+GO(usearch_getBreakIterator_66, pFp)
+GO(usearch_getMatchedLength_66, iFp)
+GO(usearch_last_66, iFpp)
+GO(usearch_openFromCollator_66, pFpipippp)
+GO(usearch_setPattern_66, vFppip)
+GO(usearch_setText_66, vFppip)
diff --git a/src/wrapped/wrappedicuuc66.c b/src/wrapped/wrappedicuuc66.c
new file mode 100644
index 0000000..de2c0c4
--- /dev/null
+++ b/src/wrapped/wrappedicuuc66.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+
+const char* icuuc66Name = "libicuuc.so.66";
+#define LIBNAME icuuc66
+
+#define CUSTOM_INIT \
+ SETALT(my66_); \
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedicuuc66_private.h b/src/wrapped/wrappedicuuc66_private.h
new file mode 100644
index 0000000..a45e54b
--- /dev/null
+++ b/src/wrapped/wrappedicuuc66_private.h
@@ -0,0 +1,86 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(ubrk_clone_66, pFpp)
+GO(ubrk_close_66, vFp)
+GO(ubrk_countAvailable_66, iFv)
+GO(ubrk_current_66, iFp)
+GO(ubrk_first_66, iFp)
+GO(ubrk_following_66, iFpi)
+GO(ubrk_getAvailable_66, pFi)
+GO(ubrk_getBinaryRules_66, iFppip)
+GO(ubrk_getLocaleByType_66, pFpip)
+GO(ubrk_getRuleStatus_66, iFp)
+GO(ubrk_getRuleStatusVec_66, iFppip)
+GO(ubrk_isBoundary_66, cFpi)
+GO(ubrk_last_66, iFp)
+GO(ubrk_next_66, iFp)
+GO(ubrk_open_66, pFppip)
+GO(ubrk_openBinaryRules_66, pFpipip)
+GO(ubrk_openRules_66, pFpipipp)
+GO(ubrk_preceding_66, iFpi)
+GO(ubrk_previous_66, iFp)
+GO(ubrk_refreshUText_66, vFppp)
+GO(ubrk_safeClone_66, pFpppp)
+GO(ubrk_setText_66, vFppip)
+GO(ubrk_setUText_66, vFppp)
+GO(ubrk_swap_66, iFppipp)
+
+GO(ucurr_forLocale_66, iFppip)
+GO(ucurr_getName_66, pFppippp)
+
+GO(uloc_canonicalize_66, iFppip)
+GO(uloc_countAvailable_66, iFv)
+GO(uloc_getAvailable_66, pFi)
+GO(uloc_getBaseName_66, iFppip)
+GO(uloc_getCharacterOrientation_66, iFpp)
+GO(uloc_getCountry_66, iFppip)
+GO(uloc_getDefault_66, pFv)
+GO(uloc_getDisplayCountry_66, iFpppip)
+GO(uloc_getDisplayLanguage_66, iFpppip)
+GO(uloc_getDisplayName_66, iFpppip)
+GO(uloc_getISO3Country_66, pFp)
+GO(uloc_getISO3Language_66, pFp)
+GO(uloc_getKeywordValue_66, iFpppip)
+GO(uloc_getLanguage_66, iFppip)
+GO(uloc_getLCID_66, uFp)
+GO(uloc_getName_66, iFppip)
+GO(uloc_getParent_66, iFppip)
+GO(uloc_setKeywordValue_66, iFpppip)
+
+GO(ures_close_66, vFp)
+GO(ures_getByKey_66, pFpppp)
+GO(ures_getSize_66, iFp)
+GO(ures_getStringByIndex_66, pFpipp)
+GO(ures_open_66, pFppp)
+
+GO(uldn_close_66, vFp)
+GO(uldn_keyValueDisplayName_66, iFppppip)
+GO(uldn_open_66, pFpip)
+
+GO(uenum_close_66, vFp)
+GO(uenum_count_66, iFpp)
+GO(uenum_next_66, pFppp)
+
+GO(uidna_close_66, vFp)
+GO(uidna_nameToASCII_66, iFppipipp)
+GO(uidna_nameToUnicode_66, iFppipipp)
+GO(uidna_openUTS46_66, pFpp)
+
+GO(unorm2_getNFCInstance_66, pFp)
+GO(unorm2_getNFDInstance_66, pFp)
+GO(unorm2_getNFKCInstance_66, pFp)
+GO(unorm2_getNFKDInstance_66, pFp)
+GO(unorm2_isNormalized_66, CFppip)
+GO(unorm2_normalize_66, iFppipip)
+
+GO(u_charsToUChars_66, vFppi)
+GO(u_getVersion_66, vFp)
+GO(u_strcmp_66, iFpp)
+GO(u_strcpy_66, pFpp)
+GO(u_strlen_66, iFp)
+GO(u_strncpy_66, pFppi)
+GO(u_tolower_66, uFu)
+GO(u_toupper_66, uFu)
+GO(u_uastrncpy_66, pFppi)
diff --git a/src/wrapped/wrappedkrb5.c b/src/wrapped/wrappedkrb5.c
index abad8c5..526d6aa 100644
--- a/src/wrapped/wrappedkrb5.c
+++ b/src/wrapped/wrappedkrb5.c
@@ -16,7 +16,12 @@
#include "librarian.h"
#include "callback.h"
-const char* krb5Name = "libkrb5.so.3";
+#ifdef ANDROID
+ const char* krb5Name = "libkrb5.so";
+#else
+ const char* krb5Name = "libkrb5.so.3";
+#endif
+
#define LIBNAME krb5
#define ADDED_FUNCTIONS() \
diff --git a/src/wrapped/wrappedlcms2.c b/src/wrapped/wrappedlcms2.c
new file mode 100644
index 0000000..e7b39e7
--- /dev/null
+++ b/src/wrapped/wrappedlcms2.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* lcms2Name = "liblcms2.so.2";
+#define LIBNAME lcms2
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedlcms2_private.h b/src/wrapped/wrappedlcms2_private.h
new file mode 100644
index 0000000..61ec0ad
--- /dev/null
+++ b/src/wrapped/wrappedlcms2_private.h
@@ -0,0 +1,368 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+//GO(_cms15Fixed16toDouble,
+//GO(_cms8Fixed8toDouble,
+//GO(cmsAdaptToIlluminant,
+//GO(_cmsAdjustEndianess16,
+//GO(_cmsAdjustEndianess32,
+//GO(_cmsAdjustEndianess64,
+//GO(cmsAllocNamedColorList,
+//GO(cmsAllocProfileSequenceDescription,
+//GO(cmsAppendNamedColor,
+//GO(cmsBFDdeltaE,
+//GO(cmsBuildGamma,
+//GO(cmsBuildParametricToneCurve,
+//GO(cmsBuildSegmentedToneCurve,
+//GO(cmsBuildTabulatedToneCurve16,
+//GO(cmsBuildTabulatedToneCurveFloat,
+//GO(_cmsCalloc,
+//GO(cmsChangeBuffersFormat,
+GO(cmsChannelsOf, uFu)
+//GO(cmsCIE2000DeltaE,
+//GO(cmsCIE94DeltaE,
+//GO(cmsCIECAM02Done,
+//GO(cmsCIECAM02Forward,
+//GO(cmsCIECAM02Init,
+//GO(cmsCIECAM02Reverse,
+//GO(cmsCloseIOhandler,
+GO(cmsCloseProfile, iFp)
+//GO(cmsCMCdeltaE,
+//GO(_cmsComputeInterpParams,
+//GO(cmsCreateBCHSWabstractProfile,
+//GO(cmsCreateBCHSWabstractProfileTHR,
+//GO(cmsCreateContext,
+//GO(cmsCreateExtendedTransform,
+//GO(cmsCreateGrayProfile,
+//GO(cmsCreateGrayProfileTHR,
+//GO(cmsCreateInkLimitingDeviceLink,
+//GO(cmsCreateInkLimitingDeviceLinkTHR,
+//GO(cmsCreateLab2Profile,
+//GO(cmsCreateLab2ProfileTHR,
+//GO(cmsCreateLab4Profile,
+//GO(cmsCreateLab4ProfileTHR,
+//GO(cmsCreateLinearizationDeviceLink,
+//GO(cmsCreateLinearizationDeviceLinkTHR,
+//GO(cmsCreateMultiprofileTransform,
+//GO(cmsCreateMultiprofileTransformTHR,
+//GO(_cmsCreateMutex,
+//GO(cmsCreateNULLProfile,
+//GO(cmsCreateNULLProfileTHR,
+//GO(cmsCreateProfilePlaceholder,
+//GO(cmsCreateProofingTransform,
+//GO(cmsCreateProofingTransformTHR,
+//GO(cmsCreateRGBProfile,
+//GO(cmsCreateRGBProfileTHR,
+GO(cmsCreate_sRGBProfile, pFp)
+//GO(cmsCreate_sRGBProfileTHR,
+GO(cmsCreateTransform, pFppupuuu)
+//GO(cmsCreateTransformTHR,
+//GO(cmsCreateXYZProfile,
+//GO(cmsCreateXYZProfileTHR,
+//GO(cmsD50_xyY,
+//GO(cmsD50_XYZ,
+//GO(_cmsDecodeDateTimeNumber,
+//GO(_cmsDefaultICCintents,
+//GO(cmsDeleteContext,
+GO(cmsDeleteTransform, vFp)
+//GO(cmsDeltaE,
+//GO(cmsDesaturateLab,
+//GO(_cmsDestroyMutex,
+//GO(cmsDetectBlackPoint,
+//GO(cmsDetectDestinationBlackPoint,
+//GO(cmsDetectTAC,
+//GO(cmsDictAddEntry,
+//GO(cmsDictAlloc,
+//GO(cmsDictDup,
+//GO(cmsDictFree,
+//GO(cmsDictGetEntryList,
+//GO(cmsDictNextEntry,
+GO(cmsDoTransform, vFpppu)
+//GO(cmsDoTransformLineStride,
+//GO(cmsDoTransformStride,
+//GO(_cmsDoubleTo15Fixed16,
+//GO(_cmsDoubleTo8Fixed8,
+//GO(cmsDupContext,
+//GO(_cmsDupMem,
+//GO(cmsDupNamedColorList,
+//GO(cmsDupProfileSequenceDescription,
+//GO(cmsDupToneCurve,
+//GO(_cmsEncodeDateTimeNumber,
+//GO(cmsEstimateGamma,
+//GO(cmsEvalToneCurve16,
+//GO(cmsEvalToneCurveFloat,
+//GO(cmsfilelength,
+//GO(_cmsFloat2Half,
+//GO(cmsFloat2LabEncoded,
+//GO(cmsFloat2LabEncodedV2,
+//GO(cmsFloat2XYZEncoded,
+//GO(cmsFormatterForColorspaceOfProfile,
+//GO(cmsFormatterForPCSOfProfile,
+//GO(_cmsFree,
+//GO(_cmsFreeInterpParams,
+//GO(cmsFreeNamedColorList,
+//GO(cmsFreeProfileSequenceDescription,
+//GO(cmsFreeToneCurve,
+//GO(cmsFreeToneCurveTriple,
+//GO(cmsGBDAlloc,
+//GO(cmsGBDFree,
+//GO(cmsGDBAddPoint,
+//GO(cmsGDBCheckPoint,
+//GO(cmsGDBCompute,
+//GO(cmsGetAlarmCodes,
+//GO(cmsGetAlarmCodesTHR,
+GO(cmsGetColorSpace, iFp)
+//GO(cmsGetContextUserData,
+//GO(cmsGetDeviceClass,
+//GO(cmsGetEncodedCMMversion,
+//GO(cmsGetEncodedICCversion,
+//GO(_cmsGetFormatter,
+//GO(cmsGetHeaderAttributes,
+//GO(cmsGetHeaderCreationDateTime,
+//GO(cmsGetHeaderCreator,
+//GO(cmsGetHeaderFlags,
+//GO(cmsGetHeaderManufacturer,
+//GO(cmsGetHeaderModel,
+//GO(cmsGetHeaderProfileID,
+//GO(cmsGetHeaderRenderingIntent,
+//GO(cmsGetNamedColorList,
+//GO(cmsGetPCS,
+//GO(cmsGetPipelineContextID,
+//GO(cmsGetPostScriptColorResource,
+//GO(cmsGetPostScriptCRD,
+//GO(cmsGetPostScriptCSA,
+//GO(cmsGetProfileContextID,
+//GO(cmsGetProfileInfo,
+//GO(cmsGetProfileInfoASCII,
+//GO(cmsGetProfileIOhandler,
+//GO(cmsGetProfileVersion,
+//GO(cmsGetSupportedIntents,
+//GO(cmsGetSupportedIntentsTHR,
+//GO(cmsGetTagCount,
+//GO(cmsGetTagSignature,
+//GO(cmsGetToneCurveEstimatedTable,
+//GO(cmsGetToneCurveEstimatedTableEntries,
+//GO(cmsGetToneCurveParametricType,
+//GO(cmsGetToneCurveParams,
+//GO(cmsGetTransformContextID,
+//GO(_cmsGetTransformFlags,
+//GO(_cmsGetTransformFormatters16,
+//GO(_cmsGetTransformFormattersFloat,
+//GO(cmsGetTransformInputFormat,
+//GO(cmsGetTransformOutputFormat,
+//GO(_cmsGetTransformUserData,
+//GO(_cmsHalf2Float,
+//GO(_cmsICCcolorSpace,
+//GO(_cmsIOPrintf,
+//GO(cmsIsCLUT,
+//GO(cmsIsIntentSupported,
+//GO(cmsIsMatrixShaper,
+//GO(cmsIsTag,
+//GO(cmsIsToneCurveDescending,
+//GO(cmsIsToneCurveLinear,
+//GO(cmsIsToneCurveMonotonic,
+//GO(cmsIsToneCurveMultisegment,
+//GO(cmsIT8Alloc,
+//GO(cmsIT8DefineDblFormat,
+//GO(cmsIT8EnumDataFormat,
+//GO(cmsIT8EnumProperties,
+//GO(cmsIT8EnumPropertyMulti,
+//GO(cmsIT8FindDataFormat,
+//GO(cmsIT8Free,
+//GO(cmsIT8GetData,
+//GO(cmsIT8GetDataDbl,
+//GO(cmsIT8GetDataRowCol,
+//GO(cmsIT8GetDataRowColDbl,
+//GO(cmsIT8GetPatchByName,
+//GO(cmsIT8GetPatchName,
+//GO(cmsIT8GetProperty,
+//GO(cmsIT8GetPropertyDbl,
+//GO(cmsIT8GetPropertyMulti,
+//GO(cmsIT8GetSheetType,
+//GO(cmsIT8LoadFromFile,
+//GO(cmsIT8LoadFromMem,
+//GO(cmsIT8SaveToFile,
+//GO(cmsIT8SaveToMem,
+//GO(cmsIT8SetComment,
+//GO(cmsIT8SetData,
+//GO(cmsIT8SetDataDbl,
+//GO(cmsIT8SetDataFormat,
+//GO(cmsIT8SetDataRowCol,
+//GO(cmsIT8SetDataRowColDbl,
+//GO(cmsIT8SetIndexColumn,
+//GO(cmsIT8SetPropertyDbl,
+//GO(cmsIT8SetPropertyHex,
+//GO(cmsIT8SetPropertyMulti,
+//GO(cmsIT8SetPropertyStr,
+//GO(cmsIT8SetPropertyUncooked,
+//GO(cmsIT8SetSheetType,
+//GO(cmsIT8SetTable,
+//GO(cmsIT8SetTableByLabel,
+//GO(cmsIT8TableCount,
+//GO(cmsJoinToneCurve,
+//GO(cmsLab2LCh,
+//GO(cmsLab2XYZ,
+//GO(cmsLabEncoded2Float,
+//GO(cmsLabEncoded2FloatV2,
+//GO(cmsLCh2Lab,
+//GO(_cmsLCMScolorSpace,
+//GO(cmsLinkTag,
+//GO(_cmsLockMutex,
+//GO(_cmsMalloc,
+//GO(_cmsMallocZero,
+//GO(_cmsMAT3eval,
+//GO(_cmsMAT3identity,
+//GO(_cmsMAT3inverse,
+//GO(_cmsMAT3isIdentity,
+//GO(_cmsMAT3per,
+//GO(_cmsMAT3solve,
+//GO(cmsMD5add,
+//GO(cmsMD5alloc,
+//GO(cmsMD5computeID,
+//GO(cmsMD5finish,
+//GO(cmsMLUalloc,
+//GO(cmsMLUdup,
+//GO(cmsMLUfree,
+//GO(cmsMLUgetASCII,
+//GO(cmsMLUgetTranslation,
+//GO(cmsMLUgetWide,
+//GO(cmsMLUsetASCII,
+//GO(cmsMLUsetWide,
+//GO(cmsMLUtranslationsCodes,
+//GO(cmsMLUtranslationsCount,
+//GO(cmsNamedColorCount,
+//GO(cmsNamedColorIndex,
+//GO(cmsNamedColorInfo,
+//GO(cmsOpenIOhandlerFromFile,
+//GO(cmsOpenIOhandlerFromMem,
+//GO(cmsOpenIOhandlerFromNULL,
+//GO(cmsOpenIOhandlerFromStream,
+//GO(cmsOpenProfileFromFile,
+//GO(cmsOpenProfileFromFileTHR,
+//GO(cmsOpenProfileFromIOhandler2THR,
+//GO(cmsOpenProfileFromIOhandlerTHR,
+GO(cmsOpenProfileFromMem, pFpu)
+//GO(cmsOpenProfileFromMemTHR,
+//GO(cmsOpenProfileFromStream,
+//GO(cmsOpenProfileFromStreamTHR,
+//GO(_cmsOptimizePipeline,
+//GO(cmsPipelineAlloc,
+//GO(cmsPipelineCat,
+//GO(cmsPipelineCheckAndRetreiveStages,
+//GO(cmsPipelineDup,
+//GO(cmsPipelineEval16,
+//GO(cmsPipelineEvalFloat,
+//GO(cmsPipelineEvalReverseFloat,
+//GO(cmsPipelineFree,
+//GO(cmsPipelineGetPtrToFirstStage,
+//GO(cmsPipelineGetPtrToLastStage,
+//GO(cmsPipelineInputChannels,
+//GO(cmsPipelineInsertStage,
+//GO(cmsPipelineOutputChannels,
+//GO(_cmsPipelineSetOptimizationParameters,
+//GO(cmsPipelineSetSaveAs8bitsFlag,
+//GO(cmsPipelineStageCount,
+//GO(cmsPipelineUnlinkStage,
+//GO(cmsPlugin,
+//GO(cmsPluginTHR,
+//GO(_cmsQuantizeVal,
+//GO(_cmsRead15Fixed16Number,
+//GO(_cmsReadAlignment,
+//GO(_cmsReadDevicelinkLUT,
+//GO(_cmsReadFloat32Number,
+//GO(_cmsReadInputLUT,
+//GO(_cmsReadOutputLUT,
+//GO(cmsReadRawTag,
+//GO(cmsReadTag,
+//GO(_cmsReadTypeBase,
+//GO(_cmsReadUInt16Array,
+//GO(_cmsReadUInt16Number,
+//GO(_cmsReadUInt32Number,
+//GO(_cmsReadUInt64Number,
+//GO(_cmsReadUInt8Number,
+//GO(_cmsReadXYZNumber,
+//GO(_cmsRealloc,
+//GO(_cmsReasonableGridpointsByColorspace,
+//GO(cmsReverseToneCurve,
+//GO(cmsReverseToneCurveEx,
+//GO(cmsSaveProfileToFile,
+//GO(cmsSaveProfileToIOhandler,
+//GO(cmsSaveProfileToMem,
+//GO(cmsSaveProfileToStream,
+//GO(cmsSetAdaptationState,
+//GO(cmsSetAdaptationStateTHR,
+//GO(cmsSetAlarmCodes,
+//GO(cmsSetAlarmCodesTHR,
+//GO(cmsSetColorSpace,
+//GO(cmsSetDeviceClass,
+//GO(cmsSetEncodedICCversion,
+//GO(cmsSetHeaderAttributes,
+//GO(cmsSetHeaderFlags,
+//GO(cmsSetHeaderManufacturer,
+//GO(cmsSetHeaderModel,
+//GO(cmsSetHeaderProfileID,
+//GO(cmsSetHeaderRenderingIntent,
+//GO(cmsSetLogErrorHandler,
+//GO(cmsSetLogErrorHandlerTHR,
+//GO(cmsSetPCS,
+//GO(cmsSetProfileVersion,
+//GO(_cmsSetTransformUserData,
+//GO(cmsSignalError,
+//GO(cmsSliceSpace16,
+//GO(cmsSliceSpaceFloat,
+//GO(cmsSmoothToneCurve,
+//GO(cmsStageAllocCLut16bit,
+//GO(cmsStageAllocCLut16bitGranular,
+//GO(cmsStageAllocCLutFloat,
+//GO(cmsStageAllocCLutFloatGranular,
+//GO(cmsStageAllocIdentity,
+//GO(_cmsStageAllocIdentityCLut,
+//GO(_cmsStageAllocIdentityCurves,
+//GO(_cmsStageAllocLab2XYZ,
+//GO(_cmsStageAllocLabV2ToV4,
+//GO(_cmsStageAllocLabV4ToV2,
+//GO(cmsStageAllocMatrix,
+//GO(_cmsStageAllocNamedColor,
+//GO(_cmsStageAllocPlaceholder,
+//GO(cmsStageAllocToneCurves,
+//GO(_cmsStageAllocXYZ2Lab,
+//GO(cmsStageData,
+//GO(cmsStageDup,
+//GO(cmsStageFree,
+//GO(cmsStageInputChannels,
+//GO(cmsStageNext,
+//GO(cmsStageOutputChannels,
+//GO(cmsStageSampleCLut16bit,
+//GO(cmsStageSampleCLutFloat,
+//GO(cmsStageType,
+//GO(cmsstrcasecmp,
+//GO(cmsTagLinkedTo,
+//GO(cmsTempFromWhitePoint,
+//GO(cmsTransform2DeviceLink,
+//GO(_cmsUnlockMutex,
+//GO(cmsUnregisterPlugins,
+//GO(cmsUnregisterPluginsTHR,
+//GO(_cmsVEC3cross,
+//GO(_cmsVEC3distance,
+//GO(_cmsVEC3dot,
+//GO(_cmsVEC3init,
+//GO(_cmsVEC3length,
+//GO(_cmsVEC3minus,
+//GO(cmsWhitePointFromTemp,
+//GO(_cmsWrite15Fixed16Number,
+//GO(_cmsWriteAlignment,
+//GO(_cmsWriteFloat32Number,
+//GO(cmsWriteRawTag,
+//GO(cmsWriteTag,
+//GO(_cmsWriteTypeBase,
+//GO(_cmsWriteUInt16Array,
+//GO(_cmsWriteUInt16Number,
+//GO(_cmsWriteUInt32Number,
+//GO(_cmsWriteUInt64Number,
+//GO(_cmsWriteUInt8Number,
+//GO(_cmsWriteXYZNumber,
+//GO(cmsxyY2XYZ,
+//GO(cmsXYZ2Lab,
+//GO(cmsXYZ2xyY,
+//GO(cmsXYZEncoded2Float,
diff --git a/src/wrapped/wrappedlib_init.h b/src/wrapped/wrappedlib_init.h
index f6b5266..75459d7 100644
--- a/src/wrapped/wrappedlib_init.h
+++ b/src/wrapped/wrappedlib_init.h
@@ -154,10 +154,12 @@ int FUNC(_init)(library_t* lib, box64context_t* box64)
for (int i = 0; i < cnt; ++i) { \
if (MAPNAME(mapname)[i].weak) { \
k = kh_put(symbolmap, lib->w.w##mapname, MAPNAME(mapname)[i].name, &ret); \
- kh_value(lib->w.w##mapname, k) = MAPNAME(mapname)[i].w; \
+ kh_value(lib->w.w##mapname, k).w = MAPNAME(mapname)[i].w; \
+ kh_value(lib->w.w##mapname, k).resolved = 0; \
} else { \
- k = kh_put(symbolmap, lib->w.mapname, MAPNAME(mapname)[i].name, &ret); \
- kh_value(lib->w.mapname, k) = MAPNAME(mapname)[i].w; \
+ k = kh_put(symbolmap, lib->w.mapname, MAPNAME(mapname)[i].name, &ret); \
+ kh_value(lib->w.mapname, k).w = MAPNAME(mapname)[i].w; \
+ kh_value(lib->w.mapname, k).resolved = 0; \
} \
if (strchr(MAPNAME(mapname)[i].name, '@')) \
AddDictionnary(box64->versym, MAPNAME(mapname)[i].name); \
@@ -168,7 +170,8 @@ int FUNC(_init)(library_t* lib, box64context_t* box64)
cnt = sizeof(MAPNAME(stsymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, lib->w.stsymbolmap, MAPNAME(stsymbolmap)[i].name, &ret);
- kh_value(lib->w.stsymbolmap, k) = MAPNAME(stsymbolmap)[i].w;
+ kh_value(lib->w.stsymbolmap, k).w = MAPNAME(stsymbolmap)[i].w;
+ kh_value(lib->w.stsymbolmap, k).resolved = 0;
if(strchr(MAPNAME(stsymbolmap)[i].name, '@'))
AddDictionnary(box64->versym, MAPNAME(stsymbolmap)[i].name);
}
@@ -178,6 +181,7 @@ int FUNC(_init)(library_t* lib, box64context_t* box64)
kh_value(lib->w.symbol2map, k).name = MAPNAME(symbol2map)[i].name2;
kh_value(lib->w.symbol2map, k).w = MAPNAME(symbol2map)[i].w;
kh_value(lib->w.symbol2map, k).weak = MAPNAME(symbol2map)[i].weak;
+ kh_value(lib->w.symbol2map, k).resolved = 0;
if(strchr(MAPNAME(symbol2map)[i].name, '@'))
AddDictionnary(box64->versym, MAPNAME(symbol2map)[i].name);
}
diff --git a/src/wrapped/wrappedlibbsd.c b/src/wrapped/wrappedlibbsd.c
new file mode 100644
index 0000000..8937ed9
--- /dev/null
+++ b/src/wrapped/wrappedlibbsd.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "elfloader.h"
+#include "box64context.h"
+#include "x64tls.h"
+
+
+#ifdef ANDROID
+const char* libbsdName = "libbsd.so";
+#else
+const char* libbsdName = "libbsd.so.0";
+#endif
+#define LIBNAME libbsd
+
+#define PRE_INIT\
+ if(1) \
+ lib->w.lib = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); \
+ else
+
+// define all standard library functions
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedlibbsd_private.h b/src/wrapped/wrappedlibbsd_private.h
new file mode 100644
index 0000000..bded8d1
--- /dev/null
+++ b/src/wrapped/wrappedlibbsd_private.h
@@ -0,0 +1,112 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GO(arc4random, uFv)
+GO(arc4random_addrandom, vFpi)
+GO(arc4random_buf, vFpL)
+GO(arc4random_stir, vFv)
+GO(arc4random_uniform, uFu)
+//GO(bsd_getopt,
+//GO(closefrom,
+//GO(dehumanize_number,
+//GO(errc,
+//GO(expand_number,
+//GO(explicit_bzero,
+//GO(__fdnlist,
+//GO(fgetln,
+//GO(fgetwln,
+//GO(flopen,
+//GO(flopenat,
+//GO(fmtcheck,
+//GO(fparseln,
+//GO(fpurge,
+//GO(freezero,
+//GO(funopen,
+//GO(getbsize,
+//GO(getmode,
+//GO(getpeereid,
+GO(getprogname, pFv)
+//GO(gid_from_group,
+//GO(group_from_gid,
+//GO(heapsort,
+//GO(humanize_number,
+//GO(inet_net_pton@@LIBBSD_0.0,
+//GO(_int_to_time,
+//GO(_long_to_time,
+//GO(MD5Data,
+//GO(MD5End,
+//GO(MD5File,
+//GO(MD5FileChunk,
+//GO(MD5Final,
+//GO(MD5Init,
+//GO(MD5Pad,
+//GO(MD5Transform,
+//GO(MD5Update,
+//GO(mergesort,
+//GO(nlist,
+//GO(nvis,
+//DATAB(optreset,
+//GO(pidfile_close,
+//GO(pidfile_fileno,
+//GO(pidfile_open,
+//GO(pidfile_remove,
+//GO(pidfile_write,
+//GO(radixsort,
+//GO(readpassphrase,
+//GO(reallocarray,
+//GO(reallocf,
+//GO(recallocarray,
+//GO(setmode,
+//GO(setproctitle@LIBBSD_0.2,
+//GO(setproctitle,
+//GO(setproctitle_init,
+GO(setprogname, vFp)
+//GO(sl_add,
+//GO(sl_find,
+//GO(sl_free,
+//GO(sl_init,
+//GO(snvis,
+//GO(sradixsort,
+//GO(stravis,
+//GO(strenvisx,
+//GO(strlcat,
+//GO(strlcpy,
+//GO(strmode,
+//GO(strnstr,
+//GO(strnunvis,
+//GO(strnunvis@LIBBSD_0.9.1,
+//GO(strnunvis_netbsd.1,
+//GO(strnunvisx,
+//GO(strnvis@LIBBSD_0.9.1,
+//GO(strnvis,
+//GO(strnvis_netbsd,
+//GO(strnvisx,
+//GO(strsenvisx,
+//GO(strsnvis,
+//GO(strsnvisx,
+//GO(strsvis,
+//GO(strsvisx,
+//GO(strtoi,
+//GO(strtonum,
+//GO(strtou,
+//GO(strunvis,
+//GO(strunvisx,
+//GO(strvis,
+//GO(strvisx,
+//GO(svis,
+//GO(_time32_to_time,
+//GO(_time64_to_time,
+//GO(_time_to_int,
+//GO(_time_to_long,
+//GO(_time_to_time32,
+//GO(_time_to_time64,
+//GO(uid_from_user,
+//GO(unvis,
+//GO(user_from_uid,
+//GO(verrc,
+//GO(vis,
+//GO(vwarnc,
+//GO(warnc,
+//GO(wcslcat,
+//GO(wcslcpy,
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 0672692..4db6b5f 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -38,6 +38,7 @@
#include <syslog.h>
#include <malloc.h>
#include <getopt.h>
+#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#undef LOG_INFO
@@ -65,7 +66,13 @@
#include "rcfile.h"
#define LIBNAME libc
-const char* libcName = "libc.so.6";
+const char* libcName =
+#ifdef ANDROID
+ "libc.so"
+#else
+ "libc.so.6"
+#endif
+ ;
typedef int (*iFi_t)(int);
typedef int (*iFp_t)(void*);
@@ -897,6 +904,7 @@ EXPORT int my_sscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* b)
}
EXPORT int my__IO_vfscanf(x64emu_t* emu, void* stream, void* fmt, void* b) __attribute__((alias("my_vfscanf")));
EXPORT int my___isoc99_vsscanf(x64emu_t* emu, void* stream, void* fmt, void* b) __attribute__((alias("my_vsscanf")));
+EXPORT int my___isoc99_vswscanf(x64emu_t* emu, void* stream, void* fmt, void* b) __attribute__((alias("my_vswscanf")));
EXPORT int my___isoc99_vfscanf(x64emu_t* emu, void* stream, void* fmt, void* b) __attribute__((alias("my_vfscanf")));
EXPORT int my___isoc99_fscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* b)
@@ -1132,7 +1140,7 @@ EXPORT int my___fxstat(x64emu_t *emu, int vers, int fd, void* buf)
(void)emu; (void)vers;
struct stat64 st;
int r = fstat64(fd, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1142,7 +1150,7 @@ EXPORT int my___fxstat64(x64emu_t *emu, int vers, int fd, void* buf)
(void)emu; (void)vers;
struct stat64 st;
int r = fstat64(fd, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1152,7 +1160,7 @@ EXPORT int my___xstat(x64emu_t* emu, int v, void* path, void* buf)
(void)emu; (void)v;
struct stat64 st;
int r = stat64((const char*)path, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1162,7 +1170,7 @@ EXPORT int my___xstat64(x64emu_t* emu, int v, void* path, void* buf)
(void)emu; (void)v;
struct stat64 st;
int r = stat64((const char*)path, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1172,7 +1180,7 @@ EXPORT int my___lxstat(x64emu_t* emu, int v, void* name, void* buf)
(void)emu; (void)v;
struct stat64 st;
int r = lstat64((const char*)name, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1182,7 +1190,7 @@ EXPORT int my___lxstat64(x64emu_t* emu, int v, void* name, void* buf)
(void)emu; (void)v;
struct stat64 st;
int r = lstat64((const char*)name, buf?&st:buf);
- if(buf)
+ if(buf && !r)
UnalignStat64(&st, buf);
return r;
}
@@ -1192,7 +1200,8 @@ EXPORT int my___fxstatat(x64emu_t* emu, int v, int d, void* path, void* buf, int
(void)emu; (void)v;
struct stat64 st;
int r = fstatat64(d, path, &st, flags);
- UnalignStat64(&st, buf);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
@@ -1201,16 +1210,18 @@ EXPORT int my___fxstatat64(x64emu_t* emu, int v, int d, void* path, void* buf, i
(void)emu; (void)v;
struct stat64 st;
int r = fstatat64(d, path, &st, flags);
- UnalignStat64(&st, buf);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
EXPORT int my_stat(x64emu_t *emu, void* filename, void* buf)
{
(void)emu;
- struct stat64 st;
- int r = stat(filename, (struct stat*)&st);
- UnalignStat64(&st, buf);
+ struct stat st;
+ int r = stat(filename, &st);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
EXPORT int my_stat64(x64emu_t *emu, void* filename, void* buf) __attribute__((alias("my_stat")));
@@ -1218,9 +1229,10 @@ EXPORT int my_stat64(x64emu_t *emu, void* filename, void* buf) __attribute__((al
EXPORT int my_lstat(x64emu_t *emu, void* filename, void* buf)
{
(void)emu;
- struct stat64 st;
- int r = lstat(filename, (struct stat*)&st);
- UnalignStat64(&st, buf);
+ struct stat st;
+ int r = lstat(filename, &st);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
EXPORT int my_lstat64(x64emu_t *emu, void* filename, void* buf) __attribute__((alias("my_lstat")));
@@ -1228,9 +1240,10 @@ EXPORT int my_lstat64(x64emu_t *emu, void* filename, void* buf) __attribute__((a
EXPORT int my_fstat(x64emu_t *emu, int fd, void* buf)
{
(void)emu;
- struct stat64 st;
- int r = fstat(fd, (struct stat*)&st);
- UnalignStat64(&st, buf);
+ struct stat st;
+ int r = fstat(fd, &st);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
EXPORT int my_fstat64(x64emu_t* emu, int fd, void* buf) __attribute__((alias("my_fstat")));
@@ -1238,9 +1251,10 @@ EXPORT int my_fstat64(x64emu_t* emu, int fd, void* buf) __attribute__((alias("my
EXPORT int my_fstatat(x64emu_t *emu, int fd, const char* path, void* buf, int flags)
{
(void)emu;
- struct stat64 st;
- int r = fstatat(fd, path, (struct stat*)&st, flags);
- UnalignStat64(&st, buf);
+ struct stat st;
+ int r = fstatat(fd, path, &st, flags);
+ if(!r)
+ UnalignStat64(&st, buf);
return r;
}
EXPORT int my_fstatat64(x64emu_t *emu, int fd, const char* path, void* buf, int flags) __attribute__((alias("my_fstatat")));
@@ -1271,6 +1285,50 @@ EXPORT int my_statfs64(const char* path, void* buf)
}
#endif
+#ifdef ANDROID
+typedef int (*__compar_d_fn_t)(const void*, const void*, void*);
+
+static size_t qsort_r_partition(void* base, size_t size, __compar_d_fn_t compar, void* arg, size_t lo, size_t hi)
+{
+ void* tmp = alloca(size);
+ void* pivot = ((char*)base) + lo * size;
+ size_t i = lo;
+ for (size_t j = lo; j <= hi; j++)
+ {
+ void* base_i = ((char*)base) + i * size;
+ void* base_j = ((char*)base) + j * size;
+ if (compar(base_j, pivot, arg) < 0)
+ {
+ memcpy(tmp, base_i, size);
+ memcpy(base_i, base_j, size);
+ memcpy(base_j, tmp, size);
+ i++;
+ }
+ }
+ void* base_i = ((char *)base) + i * size;
+ void* base_hi = ((char *)base) + hi * size;
+ memcpy(tmp, base_i, size);
+ memcpy(base_i, base_hi, size);
+ memcpy(base_hi, tmp, size);
+ return i;
+}
+
+static void qsort_r_helper(void* base, size_t size, __compar_d_fn_t compar, void* arg, ssize_t lo, ssize_t hi)
+{
+ if (lo < hi)
+ {
+ size_t p = qsort_r_partition(base, size, compar, arg, lo, hi);
+ qsort_r_helper(base, size, compar, arg, lo, p - 1);
+ qsort_r_helper(base, size, compar, arg, p + 1, hi);
+ }
+}
+
+static void qsort_r(void* base, size_t nmemb, size_t size, __compar_d_fn_t compar, void* arg)
+{
+ return qsort_r_helper(base, size, compar, arg, 0, nmemb - 1);
+}
+#endif
+
typedef struct compare_r_s {
x64emu_t* emu;
uintptr_t f;
@@ -1463,90 +1521,10 @@ EXPORT ssize_t my_readlink(x64emu_t* emu, void* path, void* buf, size_t sz)
return readlink((const char*)path, (char*)buf, sz);
}
-static int nCPU = 0;
-static double bogoMips = 100.;
-
-void grabNCpu() {
- nCPU = 1; // default number of CPU to 1
- FILE *f = fopen("/proc/cpuinfo", "r");
- size_t dummy;
- if(f) {
- nCPU = 0;
- int bogo = 0;
- size_t len = 500;
- char* line = malloc(len);
- while ((dummy = getline(&line, &len, f)) != -1) {
- if(!strncmp(line, "processor\t", strlen("processor\t")))
- ++nCPU;
- if(!bogo && !strncmp(line, "BogoMIPS\t", strlen("BogoMIPS\t"))) {
- // grab 1st BogoMIPS
- float tmp;
- if(sscanf(line, "BogoMIPS\t: %g", &tmp)==1) {
- bogoMips = tmp;
- bogo = 1;
- }
- }
- }
- free(line);
- fclose(f);
- if(!nCPU) nCPU=1;
- }
-}
-int getNCpu()
-{
- if(!nCPU)
- grabNCpu();
- return nCPU;
-}
-
-const char* getCpuName()
-{
- static char name[200] = "Unknown CPU";
- static int done = 0;
- if(done)
- return name;
- done = 1;
- FILE* f = popen("lscpu | grep \"Model name:\" | sed -r 's/Model name:\\s{1,}//g'", "r");
- if(f) {
- char tmp[200] = "";
- ssize_t s = fread(tmp, 1, 200, f);
- pclose(f);
- if(s>0) {
- // worked! (unless it's saying "lscpu: command not found" or something like that)
- if(!strstr(tmp, "lscpu")) {
- // trim ending
- while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
- tmp[strlen(tmp)-1] = 0;
- // incase multiple cpu type are present, there will be multiple lines
- while(strchr(tmp, '\n'))
- *strchr(tmp,'\n') = ' ';
- strncpy(name, tmp, 199);
- }
- return name;
- }
- }
- // failled, try to get architecture at least
- f = popen("lscpu | grep \"Architecture:\" | sed -r 's/Architecture:\\s{1,}//g'", "r");
- if(f) {
- char tmp[200] = "";
- ssize_t s = fread(tmp, 1, 200, f);
- pclose(f);
- if(s>0) {
- // worked!
- // trim ending
- while(strlen(tmp) && tmp[strlen(tmp)-1]=='\n')
- tmp[strlen(tmp)-1] = 0;
- // incase multiple cpu type are present, there will be multiple lines
- while(strchr(tmp, '\n'))
- *strchr(tmp,'\n') = ' ';
- snprintf(name, 199, "unknown %s cpu", tmp);
- return name;
- }
- }
- // Nope, bye
- return name;
-}
-
+int getNCpu(); // defined in my_cpuid.c
+const char* getBoxCpuName(); // defined in my_cpuid.c
+const char* getCpuName(); // defined in my_cpu_id.c
+double getBogoMips(); // defined in my_cpu_id.c
#ifndef NOALIGN
void CreateCPUInfoFile(int fd)
@@ -1576,7 +1554,7 @@ void CreateCPUInfoFile(int fd)
P;
sprintf(buff, "model\t\t: 1\n");
P;
- sprintf(buff, "model name\t: Intel Pentium IV @ %g%cHz\n", gigahertz?(freq/1000.):freq, gigahertz?'G':'M');
+ sprintf(buff, "model name\t: %s\n", getBoxCpuName());
P;
sprintf(buff, "stepping\t: 1\nmicrocode\t: 0x10\n");
P;
@@ -1584,15 +1562,15 @@ void CreateCPUInfoFile(int fd)
P;
sprintf(buff, "cache size\t: %d\n", 4096);
P;
- sprintf(buff, "physical id\t: %d\nsiblings\t: %d\n", i, n);
+ sprintf(buff, "physical id\t: %d\nsiblings\t: %d\n", 0, n);
P;
- sprintf(buff, "core id\t\t: %d\ncpu cores\t: %d\n", i, 1);
+ sprintf(buff, "core id\t\t: %d\ncpu cores\t: %d\n", i, n);
P;
- sprintf(buff, "bogomips\t: %g\n", bogoMips);
+ sprintf(buff, "bogomips\t: %g\n", getBogoMips());
P;
- sprintf(buff, "flags\t\t: fpu cx8 sep cmov clflush mmx sse sse2 syscall tsc lahf_lm ssse3 ht tm lm fma fxsr cpuid pclmulqdq cx16 aes movbe pni sse4_1 popcnt\n");
+ sprintf(buff, "flags\t\t: fpu cx8 sep ht cmov clflush mmx sse sse2 syscall tsc lahf_lm ssse3 ht tm lm fma fxsr cpuid pclmulqdq cx16 aes movbe pni sse4_1 sse4_2 lzcnt popcnt\n");
P;
- sprintf(buff, "address sizes\t: 46 bits physical, 48 bits virtual\n");
+ sprintf(buff, "address sizes\t: 48 bits physical, 48 bits virtual\n");
P;
sprintf(buff, "\n");
P;
@@ -1601,6 +1579,15 @@ void CreateCPUInfoFile(int fd)
#undef P
}
+#ifdef ANDROID
+static int shm_open(const char *name, int oflag, mode_t mode) {
+ return -1;
+}
+static int shm_unlink(const char *name) {
+ return -1;
+}
+#endif
+
#define TMP_CPUINFO "box64_tmpcpuinfo"
#define TMP_CPUTOPO "box64_tmpcputopo%d"
#endif
@@ -1628,7 +1615,8 @@ EXPORT int32_t my_open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t mo
int dummy = write(tmp, emu->context->fullpath, strlen(emu->context->fullpath)+1);
(void)dummy;
for (int i=1; i<emu->context->argc; ++i)
- dummy = write(tmp, emu->context->argv[i], strlen(emu->context->argv[i])+1);
+ if(emu->context->argv[i])
+ dummy = write(tmp, emu->context->argv[i], strlen(emu->context->argv[i])+1);
lseek(tmp, 0, SEEK_SET);
#endif
return tmp;
@@ -1705,7 +1693,8 @@ EXPORT int32_t my_open64(x64emu_t* emu, void* pathname, int32_t flags, uint32_t
int dummy = write(tmp, emu->context->fullpath, strlen(emu->context->fullpath)+1);
(void)dummy;
for (int i=1; i<emu->context->argc; ++i)
- dummy = write(tmp, emu->context->argv[i], strlen(emu->context->argv[i])+1);
+ if(emu->context->argv[i])
+ dummy = write(tmp, emu->context->argv[i], strlen(emu->context->argv[i])+1);
lseek(tmp, 0, SEEK_SET);
#endif
return tmp;
@@ -1843,12 +1832,14 @@ EXPORT int32_t my_epoll_pwait(x64emu_t* emu, int32_t epfd, void* events, int32_t
}
#endif
+#ifndef ANDROID
EXPORT int32_t my_glob64(x64emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pglob)
{
(void)emu;
return glob64(pat, flags, findgloberrFct(errfnc), pglob);
}
EXPORT int32_t my_glob(x64emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pglob) __attribute__((alias("my_glob64")));
+#endif
EXPORT int my_scandir64(x64emu_t *emu, void* dir, void* namelist, void* sel, void* comp)
{
@@ -2021,6 +2012,9 @@ EXPORT int32_t my_execve(x64emu_t* emu, const char* path, char* const argv[], ch
int ret = execve(path, (char* const*)newargv, envp);
return ret;
}
+ /*if(!strcmp(path + strlen(path) - strlen("/bwrap"), "/bwrap")) {
+ printf_log(LOG_NONE, "\n\n*********\n\nCalling bwrap!\n\n**********\n\n");
+ }*/
#endif
return execve(path, argv, envp);
@@ -2104,7 +2098,12 @@ EXPORT int32_t my_execl(x64emu_t* emu, const char* path)
newargv[j++] = getVargN(emu, k+1);
if(self) newargv[1] = emu->context->fullpath;
printf_log(LOG_DEBUG, " => execle(\"%s\", %p [\"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i);
- int ret = execv(newargv[0], newargv);
+ int ret = 0;
+ if (!(x64 || x86 || script || self)) {
+ ret = execv(path, newargv);
+ } else {
+ ret = execv(newargv[0], newargv);
+ }
box_free(newargv);
return ret;
}
@@ -2228,6 +2227,10 @@ EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
int script = (my_context->bashpath && FileIsShell(fullpath))?1:0;
int ret;
printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x64, fullpath);
+ // hack to update the environ var if needed
+ if(envp == my_context->envv && environ) {
+ envp = environ;
+ }
if (x64 || x86 || script || self) {
int n=1;
while(argv[n]) ++n;
@@ -2435,6 +2438,11 @@ void InitCpuModel()
}
#endif
+#ifdef ANDROID
+void ctSetup()
+{
+}
+#else
EXPORT const unsigned short int *my___ctype_b;
EXPORT const int32_t *my___ctype_tolower;
EXPORT const int32_t *my___ctype_toupper;
@@ -2445,6 +2453,7 @@ void ctSetup()
my___ctype_toupper = *(__ctype_toupper_loc());
my___ctype_tolower = *(__ctype_tolower_loc());
}
+#endif
EXPORT void my___register_frame_info(void* a, void* b)
{
@@ -2459,24 +2468,6 @@ EXPORT void* my___deregister_frame_info(void* a)
EXPORT void* my____brk_addr = NULL;
-// longjmp / setjmp
-typedef struct jump_buff_x64_s {
- uint64_t save_rbx;
- uint64_t save_rbp;
- uint64_t save_r12;
- uint64_t save_r13;
- uint64_t save_r14;
- uint64_t save_r15;
- uint64_t save_rsp;
- uint64_t save_rip;
-} jump_buff_x64_t;
-
-typedef struct __jmp_buf_tag_s {
- jump_buff_x64_t __jmpbuf;
- int __mask_was_saved;
- __sigset_t __saved_mask;
-} __jmp_buf_tag_t;
-
void EXPORT my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val)
{
jump_buff_x64_t *jpbuff = &((__jmp_buf_tag_t*)p)->__jmpbuf;
@@ -2562,47 +2553,62 @@ EXPORT int my_readlinkat(x64emu_t* emu, int fd, void* path, void* buf, size_t bu
}
return readlinkat(fd, path, buf, bufsize);
}
-
-EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset)
+#ifndef MAP_FIXED_NOREPLACE
+#define MAP_FIXED_NOREPLACE 0x200000
+#endif
+#ifndef MAP_32BIT
+#define MAP_32BIT 0x40
+#endif
+EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset)
{
(void)emu;
if(prot&PROT_WRITE)
prot|=PROT_READ; // PROT_READ is implicit with PROT_WRITE on i386
- if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) => ", addr, length, prot, flags, fd, offset);}
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "mmap64(%p, 0x%lx, 0x%x, 0x%x, %d, %ld) => ", addr, length, prot, flags, fd, offset);}
+ int new_flags = flags;
#ifndef NOALIGN
void* old_addr = addr;
- if(flags&0x40) {
- // 0x40 is MAP_32BIT, wich only exist on x86_64!
- //flags &= ~0x40; // let the flags in?
- addr = find31bitBlockNearHint(addr, length);
+ new_flags&=~MAP_32BIT; // remove MAP_32BIT
+ if(flags&MAP_32BIT) {
+ // MAP_32BIT only exist on x86_64!
+ addr = find31bitBlockNearHint(addr, length, 0);
} else if (box64_wine || 1) { // other mmap should be restricted to 47bits
if(!addr)
addr = find47bitBlock(length);
}
#endif
- void* ret = mmap64(addr, length, prot, flags, fd, offset);
+ void* ret = mmap64(addr, length, prot, new_flags, fd, offset);
#ifndef NOALIGN
- if((ret!=(void*)-1) && (flags&0x40) &&
- (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff)))) {
+ if((ret!=MAP_FAILED) && (flags&MAP_32BIT) &&
+ (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff) && (ret!=addr)))) {
printf_log(LOG_DEBUG, "Warning, mmap on 32bits didn't worked, ask %p, got %p ", addr, ret);
munmap(ret, length);
loadProtectionFromMap(); // reload map, because something went wrong previously
- addr = find31bitBlockNearHint(old_addr, length); // is this the best way?
- ret = mmap64(addr, length, prot, flags, fd, offset);
+ addr = find31bitBlockNearHint(old_addr, length, 0); // is this the best way?
+ new_flags = (addr && isBlockFree(addr, length) )? (new_flags|MAP_FIXED) : new_flags;
+ if(new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE)==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE;
+ ret = mmap64(addr, length, prot, new_flags, fd, offset);
printf_log(LOG_DEBUG, " tried again with %p, got %p\n", addr, ret);
- } else if((ret!=(void*)-1) && !(flags&MAP_FIXED) && (box64_wine) && (old_addr) && (addr!=ret) &&
+ } else if((ret!=MAP_FAILED) && !(flags&MAP_FIXED) && (box64_wine) && (old_addr) && (addr!=ret) &&
(((uintptr_t)ret>0x7fffffffffffLL) || ((uintptr_t)ret&~0xffff))) {
printf_log(LOG_DEBUG, "Warning, mmap on 47bits didn't worked, ask %p, got %p ", addr, ret);
munmap(ret, length);
loadProtectionFromMap(); // reload map, because something went wrong previously
- addr = find47bitBlockNearHint(old_addr, length); // is this the best way?
- ret = mmap64(addr, length, prot, flags, fd, offset);
+ addr = find47bitBlockNearHint(old_addr, length, 0); // is this the best way?
+ new_flags = (addr && isBlockFree(addr, length)) ? (new_flags|MAP_FIXED) : new_flags;
+ if(new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE)==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE;
+ ret = mmap64(addr, length, prot, new_flags, fd, offset);
printf_log(LOG_DEBUG, " tried again with %p, got %p\n", addr, ret);
}
#endif
- if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "%p\n", ret);}
+ if((ret!=MAP_FAILED) && (flags&MAP_FIXED_NOREPLACE) && (ret!=addr)) {
+ munmap(ret, length);
+ errno = EEXIST;
+ return MAP_FAILED;
+ }
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "%p\n", ret);}
#ifdef DYNAREC
- if(box64_dynarec && ret!=(void*)-1) {
+ if(box64_dynarec && ret!=MAP_FAILED) {
/*if(flags&0x100000 && addr!=ret)
{
// program used MAP_FIXED_NOREPLACE but the host linux didn't support it
@@ -2615,59 +2621,62 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
}
}
#endif
- if(ret!=(void*)-1) {
- setProtection_mmap((uintptr_t)ret, length, prot);
+ if(ret!=MAP_FAILED) {
+ if(emu)
+ setProtection_mmap((uintptr_t)ret, length, prot);
+ else
+ setProtection((uintptr_t)ret, length, prot);
}
return ret;
}
-EXPORT void* my_mmap(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset) __attribute__((alias("my_mmap64")));
+EXPORT void* my_mmap(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) __attribute__((alias("my_mmap64")));
EXPORT void* my_mremap(x64emu_t* emu, void* old_addr, size_t old_size, size_t new_size, int flags, void* new_addr)
{
(void)emu;
- dynarec_log(LOG_DEBUG, "mremap(%p, %lu, %lu, %d, %p)=>", old_addr, old_size, new_size, flags, new_addr);
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "mremap(%p, %lu, %lu, %d, %p)=>", old_addr, old_size, new_size, flags, new_addr);}
void* ret = mremap(old_addr, old_size, new_size, flags, new_addr);
- dynarec_log(LOG_DEBUG, "%p\n", ret);
- if(ret==(void*)-1)
- return ret; // failed...
- uint32_t prot = getProtection((uintptr_t)old_addr)&~PROT_CUSTOM;
- if(ret==old_addr) {
- if(old_size && old_size<new_size) {
- setProtection_mmap((uintptr_t)ret+old_size, new_size-old_size, prot);
- #ifdef DYNAREC
- if(box64_dynarec)
- addDBFromAddressRange((uintptr_t)ret+old_size, new_size-old_size);
- #endif
- } else if(old_size && new_size<old_size) {
- freeProtection((uintptr_t)ret+new_size, old_size-new_size);
- #ifdef DYNAREC
- if(box64_dynarec)
- cleanDBFromAddressRange((uintptr_t)ret+new_size, old_size-new_size, 1);
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "%p\n", ret);}
+ if(ret!=(void*)-1) {
+ uint32_t prot = getProtection((uintptr_t)old_addr)&~PROT_CUSTOM;
+ if(ret==old_addr) {
+ if(old_size && old_size<new_size) {
+ setProtection_mmap((uintptr_t)ret+old_size, new_size-old_size, prot);
+ #ifdef DYNAREC
+ if(box64_dynarec)
+ addDBFromAddressRange((uintptr_t)ret+old_size, new_size-old_size);
+ #endif
+ } else if(old_size && new_size<old_size) {
+ freeProtection((uintptr_t)ret+new_size, old_size-new_size);
+ #ifdef DYNAREC
+ if(box64_dynarec)
+ cleanDBFromAddressRange((uintptr_t)ret+new_size, old_size-new_size, 1);
+ #endif
+ } else if(!old_size) {
+ setProtection_mmap((uintptr_t)ret, new_size, prot);
+ #ifdef DYNAREC
+ if(box64_dynarec)
+ addDBFromAddressRange((uintptr_t)ret, new_size);
+ #endif
+ }
+ } else {
+ if(old_size
+ #ifdef MREMAP_DONTUNMAP
+ && ((flags&MREMAP_DONTUNMAP)==0)
#endif
- } else if(!old_size) {
- setProtection_mmap((uintptr_t)ret, new_size, prot);
+ ) {
+ freeProtection((uintptr_t)old_addr, old_size);
+ #ifdef DYNAREC
+ if(box64_dynarec)
+ cleanDBFromAddressRange((uintptr_t)old_addr, old_size, 1);
+ #endif
+ }
+ setProtection_mmap((uintptr_t)ret, new_size, prot); // should copy the protection from old block
#ifdef DYNAREC
if(box64_dynarec)
addDBFromAddressRange((uintptr_t)ret, new_size);
#endif
}
- } else {
- if(old_size
- #ifdef MREMAP_DONTUNMAP
- && ((flags&MREMAP_DONTUNMAP)==0)
- #endif
- ) {
- freeProtection((uintptr_t)old_addr, old_size);
- #ifdef DYNAREC
- if(box64_dynarec)
- cleanDBFromAddressRange((uintptr_t)old_addr, old_size, 1);
- #endif
- }
- setProtection_mmap((uintptr_t)ret, new_size, prot); // should copy the protection from old block
- #ifdef DYNAREC
- if(box64_dynarec)
- addDBFromAddressRange((uintptr_t)ret, new_size);
- #endif
}
return ret;
}
@@ -2675,13 +2684,13 @@ EXPORT void* my_mremap(x64emu_t* emu, void* old_addr, size_t old_size, size_t ne
EXPORT int my_munmap(x64emu_t* emu, void* addr, unsigned long length)
{
(void)emu;
- dynarec_log(LOG_DEBUG, "munmap(%p, %lu)\n", addr, length);
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "munmap(%p, %lu)\n", addr, length);}
+ int ret = munmap(addr, length);
#ifdef DYNAREC
- if(box64_dynarec && length) {
+ if(!ret && box64_dynarec && length) {
cleanDBFromAddressRange((uintptr_t)addr, length, 1);
}
#endif
- int ret = munmap(addr, length);
if(!ret) {
freeProtection((uintptr_t)addr, length);
}
@@ -2691,7 +2700,7 @@ EXPORT int my_munmap(x64emu_t* emu, void* addr, unsigned long length)
EXPORT int my_mprotect(x64emu_t* emu, void *addr, unsigned long len, int prot)
{
(void)emu;
- dynarec_log(LOG_DEBUG, "mprotect(%p, %lu, 0x%x)\n", addr, len, prot);
+ if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "mprotect(%p, %lu, 0x%x)\n", addr, len, prot);}
if(prot&PROT_WRITE)
prot|=PROT_READ; // PROT_READ is implicit with PROT_WRITE on x86_64
int ret = mprotect(addr, len, prot);
@@ -2755,6 +2764,7 @@ EXPORT int my_getopt_long_only(int argc, char* const argv[], const char* optstri
return ret;
}
+#ifndef ANDROID
typedef struct {
void *read;
void *write;
@@ -2802,6 +2812,7 @@ EXPORT void* my_fopencookie(x64emu_t* emu, void* cookie, void* mode, my_cookie_i
cb->cookie = cookie;
return fopencookie(cb, mode, io_funcs);
}
+#endif
#if 0
@@ -2865,14 +2876,26 @@ EXPORT int my_nanosleep(const struct timespec *req, struct timespec *rem)
}
#endif
+#ifdef ANDROID
+void obstackSetup() {
+}
+#else
// all obstack function defined in obstack.c file
void obstackSetup();
+#endif
EXPORT void* my_malloc(unsigned long size)
{
return calloc(1, size);
}
+EXPORT int my_setrlimit(x64emu_t* emu, int ressource, const struct rlimit *rlim)
+{
+ int ret = (ressource==RLIMIT_AS)?0:setrlimit(ressource, rlim);
+ if(ressource==RLIMIT_AS) printf_log(LOG_DEBUG, " (ignored) RLIMIT_AS, cur=0x%lx, max=0x%lx ", rlim->rlim_cur, rlim->rlim_max);
+ return ret;
+}
+
#if 0
#ifdef PANDORA
#define RENAME_NOREPLACE (1 << 0)
@@ -2955,6 +2978,7 @@ EXPORT void my_mcount(void* frompc, void* selfpc)
}
#endif
+#ifndef ANDROID
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
@@ -2962,6 +2986,7 @@ union semun {
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
+#endif
#ifndef SEM_STAT_ANY
#define SEM_STAT_ANY 20
#endif
@@ -2987,17 +3012,36 @@ EXPORT int my_semctl(int semid, int semnum, int cmd, union semun b)
return ret;
}
-EXPORT int my_ptrace(x64emu_t* emu, int request, pid_t pid, void* addr, void* data)
+EXPORT uint64_t userdata_sign = 0x1234598765ABCEF0;
+EXPORT uint32_t userdata[1024];
+
+EXPORT long my_ptrace(x64emu_t* emu, int request, pid_t pid, void* addr, uint32_t* data)
{
if(request == PTRACE_POKEUSER) {
+ if(ptrace(PTRACE_PEEKDATA, pid, &userdata_sign, NULL)==userdata_sign && (uintptr_t)addr < sizeof(userdata)) {
+ ptrace(PTRACE_POKEDATA, pid, addr+(uintptr_t)userdata, data);
+ return 0;
+ }
+ // fallback to a generic local faking
+ if((uintptr_t)addr < sizeof(userdata))
+ *(uintptr_t*)(addr+(uintptr_t)userdata) = (uintptr_t)data;
// lets just ignore this for now!
return 0;
}
+ if(request == PTRACE_PEEKUSER) {
+ if(ptrace(PTRACE_PEEKDATA, pid, &userdata_sign, NULL)==userdata_sign && (uintptr_t)addr < sizeof(userdata)) {
+ return ptrace(PTRACE_PEEKDATA, pid, addr+(uintptr_t)userdata, data);
+ }
+ // fallback to a generic local faking
+ if((uintptr_t)addr < sizeof(userdata))
+ return *(uintptr_t*)(addr+(uintptr_t)userdata);
+ }
return ptrace(request, pid, addr, data);
}
// Backtrace stuff
+#ifndef ANDROID
#include "elfs/elfdwarf_private.h"
EXPORT int my_backtrace(x64emu_t* emu, void** buffer, int size)
{
@@ -3123,6 +3167,7 @@ EXPORT void my_backtrace_symbols_fd(x64emu_t* emu, uintptr_t* buffer, int size,
(void)dummy;
}
}
+#endif
EXPORT int my_iopl(x64emu_t* emu, int level)
{
@@ -3302,6 +3347,16 @@ EXPORT int my_prctl(x64emu_t* emu, int option, unsigned long arg2, unsigned long
return prctl(option, arg2, arg3, arg4, arg5);
}
+#ifndef _SC_NPROCESSORS_ONLN
+#define _SC_NPROCESSORS_ONLN 84
+#endif
+EXPORT long my_sysconf(x64emu_t* emu, int what) {
+ if(what==_SC_NPROCESSORS_ONLN) {
+ return getNCpu();
+ }
+ return sysconf(what);
+}
+EXPORT long my___sysconf(x64emu_t* emu, int what) __attribute__((alias("my_sysconf")));
EXPORT char* my___progname = NULL;
EXPORT char* my___progname_full = NULL;
@@ -3316,6 +3371,32 @@ EXPORT char my___libc_single_threaded = 0;
lib->w.lib = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); \
else
+#ifdef ANDROID
+#define NEEDED_LIBS 1, \
+ "libbsd.so"
+#define NEEDED_LIBS_234 4, \
+ "libpthread.so.0", \
+ "libdl.so.2" , \
+ "libm.so", \
+ "libbsd.so"
+#else
+#define NEEDED_LIBS 6, \
+ "ld-linux-x86-64.so.2", \
+ "libpthread.so.0", \
+ "libdl.so.2", \
+ "libutil.so.1", \
+ "librt.so.1", \
+ "libbsd.so.0"
+#define NEEDED_LIBS_234 7, \
+ "ld-linux-x86-64.so.2", \
+ "libpthread.so.0", \
+ "libdl.so.2", \
+ "libutil.so.1", \
+ "libresolv.so.2", \
+ "librt.so.1", \
+ "libbsd.so.0"
+#endif
+
#define CUSTOM_INIT \
box64->libclib = lib; \
/*InitCpuModel();*/ \
@@ -3327,19 +3408,9 @@ EXPORT char my___libc_single_threaded = 0;
strrchr(box64->argv[0], '/') + 1; \
getMy(lib); \
if(box64_isglibc234) \
- setNeededLibs(lib, 6, \
- "ld-linux-x86-64.so.2", \
- "libpthread.so.0", \
- "libdl.so.2", \
- "libutil.so.1", \
- "libresolv.so.2", \
- "librt.so.1"); \
+ setNeededLibs(lib, NEEDED_LIBS_234); \
else \
- setNeededLibs(lib, 4, \
- "ld-linux-x86-64.so.2", \
- "libpthread.so.0", \
- "libutil.so.1", \
- "librt.so.1");
+ setNeededLibs(lib, NEEDED_LIBS);
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 933178e..6dd94b4 100644
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -96,7 +96,7 @@ GOW(btowc, uFi)
GO(__bzero, vFpL)
GO(bzero, vFpL)
//GO(c16rtomb, LFpW!)
-//GOW(c32rtomb, LFpu!)
+GOW(c32rtomb, LFpup)
GOW(calloc, pFLL)
//GO(callrpc, iFpLLL@p@p)
//GO(__call_tls_dtors, vFv)
@@ -366,8 +366,8 @@ GO(fgetws, pFpip)
GO(fgetws_unlocked, pFpip)
//GO(__fgetws_unlocked_chk,
GO(fgetxattr, lFippL)
-GOW(fileno, iFp)
-GOW(fileno_unlocked, iFp)
+GOW(fileno, iFS)
+GOW(fileno_unlocked, iFS)
GO(__finite, iFd)
GOW(finite, iFd)
GO(__finitef, iFf)
@@ -925,16 +925,20 @@ GO(__isnanf, iFf)
GOW(isnanf, iFf)
GO(__isnanl, iFD)
GOW(isnanl, iFD)
+GO2(__isoc23_fscanf, iFEppV, my___isoc99_fscanf)
+GO2(__isoc23_sscanf, iFEppV, my___isoc99_sscanf)
+GO2(__isoc23_strtol, lFppi, strtol)
+GO2(__isoc23_strtoul, LFppi, strtoul)
GOM(__isoc99_fscanf, iFEppV)
//GO(__isoc99_fwscanf, iFppV)
GOM(__isoc99_scanf, iFEpV)
GOM(__isoc99_sscanf, iFEppV)
GOM(__isoc99_swscanf, iFEppV)
-GOM(__isoc99_vfscanf, iFEppp)
+GOM(__isoc99_vfscanf, iFEppA)
//GO(__isoc99_vfwscanf, iFppA)
//GO(__isoc99_vscanf, iFpA)
-GOM(__isoc99_vsscanf, iFEppp)
-//GO(__isoc99_vswscanf, iFppA)
+GOM(__isoc99_vsscanf, iFEppA)
+GOM(__isoc99_vswscanf, iFEppA)
//GO(__isoc99_vwscanf, iFpA)
//GO(__isoc99_wscanf, iFpV)
GO(isprint, iFi)
@@ -1131,7 +1135,7 @@ GO(mblen, iFpU)
GO(__mbrlen, LFpLp)
GO(mbrlen, LFpLp)
//GO(mbrtoc16, LFppL!)
-//GOW(mbrtoc32, LFppL!)
+GOW(mbrtoc32, LFppLp)
GO(__mbrtowc, LFppLp)
GO(mbrtowc, LFppLp)
GOW(mbsinit, iFp)
@@ -1140,7 +1144,7 @@ GO(__mbsnrtowcs_chk, LFppLLpL)
GO(mbsrtowcs, LFppLp)
GO(__mbsrtowcs_chk, LFppLpL)
GO(mbstowcs, LFppL)
-//GO(__mbstowcs_chk,
+GO(__mbstowcs_chk, LFppLL)
GO(mbtowc, iFppL)
//GO(mcheck, iF@)
GO(mcheck_check_all, vFv)
@@ -1389,37 +1393,132 @@ DATA(__progname_full, sizeof(void))
GOW(pselect, iFippppp)
GO(psiginfo, vFpp)
GO(psignal, vFip)
-//GO(pthread_attr_destroy,
-//GO(pthread_attr_getdetachstate,
-//GO(pthread_attr_getinheritsched,
-//GO(pthread_attr_getschedparam,
-//GO(pthread_attr_getschedpolicy,
-//GO(pthread_attr_getscope,
-//GO(pthread_attr_init,
-//GO(pthread_attr_setdetachstate,
-//GO(pthread_attr_setinheritsched,
-//GO(pthread_attr_setschedparam,
-//GO(pthread_attr_setschedpolicy,
-//GO(pthread_attr_setscope,
-//GO(pthread_condattr_destroy,
-//GO(pthread_condattr_init,
-//GO(pthread_cond_broadcast,
-//GO(pthread_cond_destroy,
-//GO(pthread_cond_init,
-//GO(pthread_cond_signal,
-//GO(pthread_cond_timedwait,
-//GO(pthread_cond_wait,
-//GO(pthread_equal,
-//GO(pthread_exit,
-//GO(pthread_getschedparam,
-//GO(pthread_mutex_destroy,
-//GO(pthread_mutex_init,
-//GO(pthread_mutex_lock,
-//GO(pthread_mutex_unlock,
-//GO(pthread_self,
-//GO(pthread_setcancelstate,
-//GO(pthread_setcanceltype,
-//GO(pthread_setschedparam,
+GO(__sF, vFip)
+GO(__assert2, vFip)
+
+GOM(pthread_atfork, iFEppp)
+GOM(pthread_attr_destroy, iFEp)
+GOM(pthread_attr_getdetachstate, iFEpp)
+GOM(pthread_attr_getguardsize, iFEpp)
+GOM(pthread_attr_getinheritsched, iFEpp)
+GOM(pthread_attr_getschedparam, iFEpp)
+GOM(pthread_attr_getschedpolicy, iFEpp)
+GOM(pthread_attr_getscope, iFEpp)
+GOM(pthread_attr_getstack, iFEppp)
+GOM(pthread_attr_getstackaddr, iFEpp)
+GOM(pthread_attr_getstacksize, iFEpp)
+GOM(pthread_attr_init, iFEp)
+GOM(pthread_attr_setaffinity_np, iFEpLp)
+GOM(pthread_attr_setdetachstate, iFEpi)
+GOM(pthread_attr_setguardsize, iFEpL)
+GOM(pthread_attr_setinheritsched, iFEpi)
+GOM(pthread_attr_setschedparam, iFEpp)
+GOM(pthread_attr_setschedpolicy, iFEpi)
+GOM(pthread_attr_setscope, iFEpi)
+GOM(pthread_attr_setstackaddr, iFEpp)
+GOM(pthread_attr_setstack, iFEppL)
+GOM(pthread_attr_setstacksize, iFEpL)
+GOM(pthread_barrierattr_destroy, iFEp)
+GOM(pthread_barrierattr_getpshared, iFEpp)
+GOM(pthread_barrierattr_init, iFEp)
+GOM(pthread_barrierattr_setpshared, iFEpi)
+GO(pthread_barrier_destroy, iFp)
+GOM(pthread_barrier_init, iFEppu)
+GO(pthread_barrier_wait, iFp)
+GO(pthread_cancel, iFL)
+GOM(pthread_condattr_destroy, iFEp)
+GOM(pthread_condattr_getclock, iFEpp)
+GOM(pthread_condattr_getpshared, iFEpp)
+GOM(pthread_condattr_init, iFEp)
+GOM(pthread_condattr_setclock, iFEpi)
+GOM(pthread_condattr_setpshared, iFEpi)
+GOM(pthread_cond_broadcast, iFEp)
+GOM(pthread_cond_destroy, iFEp)
+GOM(pthread_cond_init, iFEpp)
+GO(pthread_cond_signal, iFp)
+GOM(pthread_cond_timedwait, iFEppp)
+GOM(pthread_cond_wait, iFEpp)
+GOM(pthread_create, iFEpppp)
+GOM(pthread_cond_clockwait, iFEppip)
+GO(pthread_detach, iFL)
+GO(pthread_equal, iFLL)
+GO(pthread_exit, vFp)
+GOM(pthread_getaffinity_np, iFEpLp)
+GOM(pthread_getattr_np, iFELp)
+GOM(pthread_getattr_default_np, iFEp)
+GOM(pthread_setattr_default_np, iFEp)
+GO(pthread_getcpuclockid, iFLp)
+GO(pthread_getschedparam, iFLpp)
+GO(pthread_getspecific, pFL)
+GO(pthread_getname_np, iFppL)
+GO(pthread_join, iFLp)
+GOM(pthread_key_create, iFEpp)
+GO(pthread_key_delete, iFL)
+GO2(pthread_kill@GLIBC_2.2.5, iFEpi, my_pthread_kill_old)
+GOM(pthread_kill, iFEpi)
+GO(pthread_kill_other_threads_np, vFv)
+GOM(pthread_mutexattr_destroy, iFEp)
+GOM(pthread_mutexattr_getkind_np, iFEpp)
+GOM(pthread_mutexattr_getprotocol, iFEpp)
+GOM(pthread_mutexattr_getrobust, iFEpp)
+GOM(pthread_mutexattr_gettype, iFEpp)
+GOM(pthread_mutexattr_init, iFEp)
+GOM(pthread_mutexattr_setkind_np, iFEpi)
+GOM(pthread_mutexattr_setprotocol, iFEpi)
+GOM(pthread_mutexattr_setpshared, iFEpi)
+GOM(pthread_mutexattr_setrobust, iFEpi)
+GOM(pthread_mutexattr_settype, iFEpi)
+GO(pthread_mutex_consistent, iFp)
+GO(pthread_mutex_destroy, iFp)
+// phtread_mutex_t is 40 bytes on x86_64, but 48bytes on ARM64
+GOM(pthread_mutex_init, iFpp)
+GO(pthread_mutex_lock, iFp)
+GO(pthread_mutex_timedlock, iFpp)
+GO(pthread_mutex_trylock, iFp)
+GO(pthread_mutex_unlock, iFp)
+GOM(pthread_once, iFEpp)
+GO(pthread_rwlockattr_destroy, vFp)
+GO(pthread_rwlockattr_getkind_np, iFpp)
+GO(pthread_rwlockattr_init, iFp)
+GO(pthread_rwlockattr_setkind_np, iFpi)
+GO(pthread_rwlock_destroy, iFp)
+GO(pthread_rwlock_init, iFpp)
+GO(pthread_rwlock_rdlock, iFp)
+GO(pthread_rwlock_tryrdlock, iFp)
+GO(pthread_rwlock_trywrlock, iFp)
+GO(pthread_rwlock_unlock, iFp)
+GO(pthread_rwlock_wrlock, iFp)
+GO(pthread_self, LFv)
+GOM(pthread_setaffinity_np, iFEpLp)
+GO(pthread_setcancelstate, iFip)
+GO(pthread_setcanceltype, iFip)
+GO(pthread_setconcurrency, iFi)
+GO(pthread_setname_np, iFpp)
+GO(pthread_setschedparam, iFLip)
+GO(pthread_setschedprio, iFpi)
+GO(pthread_setspecific, iFLp)
+GO(pthread_sigmask, iFipp)
+GO(pthread_spin_destroy, iFp)
+GO(pthread_spin_init, iFpi)
+GO(pthread_spin_lock, iFp)
+GO(pthread_spin_trylock, iFp)
+GO(pthread_spin_unlock, iFp)
+GO(pthread_testcancel, vFv)
+GO(pthread_timedjoin_np, iFppp)
+GO(pthread_tryjoin_np, iFpp)
+GO(pthread_yield, iFv)
+GO(sem_close, iFp)
+GO(sem_clockwait, iFppp)
+GO(sem_destroy, iFp)
+GO(sem_getvalue, iFpp)
+GO(sem_init, iFpiu)
+GO(sem_open, pFpOM)
+GO(sem_post, iFp)
+GO(sem_timedwait, iFpp)
+GO(sem_trywait, iFp)
+GO(sem_unlink, iFp)
+GO(sem_wait, iFp)
+
GOM(ptrace, lFEuipp)
GO(ptsname, pFi)
GOW(ptsname_r, iFipL)
@@ -1650,7 +1749,7 @@ GOW(setregid, iFuu)
GOW(setresgid, iFuuu)
GOW(setresuid, iFuuu)
GOW(setreuid, iFuu)
-GOW(setrlimit, iFup)
+GOWM(setrlimit, iFEup)
GOW(setrlimit64, iFup)
GO(setrpcent, vFi)
GO(setservent, vFi)
@@ -1932,8 +2031,8 @@ GO(sync, vFv)
GO(sync_file_range, iFillu)
GO(syncfs, iFi)
GOM(syscall, lFEv)
-GO(__sysconf, lFi)
-GO(sysconf, IFi)
+GOM(__sysconf, lFEi)
+GOM(sysconf, IFEi)
GO(__sysctl, iFpipppL)
GOW(sysctl, iFpipppL) // Deprecated
DATA(_sys_errlist, sizeof(void*))
@@ -2326,3 +2425,12 @@ DATAM(__libc_single_threaded, 1)
GO(iconvctl, iFlip)
GO(dummy__ZnwmSt11align_val_tRKSt9nothrow_t, pFLLp) // for mallochook.c
+
+#ifdef ANDROID
+GOM(__libc_init, vFEpppp)
+GO(__errno, pFv)
+#else
+// Those symbols don't exist in non-Android builds
+//GOM(__libc_init,
+//GO(__errno,
+#endif
diff --git a/src/wrapped/wrappedlibcups.c b/src/wrapped/wrappedlibcups.c
index 16ea472..dc84686 100644
--- a/src/wrapped/wrappedlibcups.c
+++ b/src/wrapped/wrappedlibcups.c
@@ -18,7 +18,14 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
-const char* libcupsName = "libcups.so.2";
+const char* libcupsName =
+#ifdef ANDROID
+ "libcups.so"
+#else
+ "libcups.so.2"
+#endif
+ ;
+
#define LIBNAME libcups
#define ADDED_FUNCTIONS() \
diff --git a/src/wrapped/wrappedlibcups_private.h b/src/wrapped/wrappedlibcups_private.h
index 4978426..eb87044 100644
--- a/src/wrapped/wrappedlibcups_private.h
+++ b/src/wrapped/wrappedlibcups_private.h
@@ -57,7 +57,7 @@ GO(cupsCopyDest, iFpip)
//GO(cupsCopyDestInfo,
//GO(_cupsCreateDest,
//GO(cupsCreateDestJob,
-//GO(cupsCreateJob,
+GO(cupsCreateJob, iFpppip)
//DATA(_cups_debug_fd,
//DATA(_cups_debug_level,
//GO(cupsDirClose,
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 47c47c6..217ae01 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -57,9 +57,13 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) EXPORT;
#define LIBNAME libdl
-const char* libdlName = "libdl.so.2";
+#ifdef ANDROID
+ const char* libdlName = "libdl.so";
+#else
+ const char* libdlName = "libdl.so.2";
+#endif
-#define CLEARERR if(dl->last_error) box_free(dl->last_error); dl->last_error = NULL;
+#define CLEARERR if(dl->last_error) {box_free(dl->last_error); dl->last_error = NULL;}
void RemoveDlopen(library_t** lib, int idx)
{
@@ -180,7 +184,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
if(AddNeededLib(NULL, is_local, bindnow, tmp, NULL, my_context, emu)) {
printf_dlsym(strchr(rfilename,'/')?LOG_DEBUG:LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
RemoveNeededLib(NULL, is_local, tmp, my_context, emu);
return NULL;
@@ -290,7 +294,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
return (void*)start;
}
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
pthread_mutex_unlock(&mutex);
@@ -307,7 +311,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
return (void*)start;
}
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
pthread_mutex_unlock(&mutex);
@@ -318,7 +322,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
// size_t is unsigned
if(nlib>=dl->lib_sz) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
pthread_mutex_unlock(&mutex);
@@ -326,7 +330,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
}
if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
printf_dlsym(LOG_NEVER, "%p\n", (void*)NULL);
pthread_mutex_unlock(&mutex);
@@ -340,7 +344,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
printf_dlsym(LOG_NEVER, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol);
printf_log(LOG_DEBUG, " Symbol not found\n");
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
pthread_mutex_unlock(&mutex);
return NULL;
@@ -356,7 +360,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
return (void*)start;
}
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
pthread_mutex_unlock(&mutex);
@@ -377,14 +381,14 @@ int my_dlclose(x64emu_t* emu, void *handle)
// size_t is unsigned
if(nlib>=dl->lib_sz) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_error);
return -1;
}
if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_error);
return -1;
@@ -393,6 +397,15 @@ int my_dlclose(x64emu_t* emu, void *handle)
DecRefCount(&dl->dllibs[nlib].lib, emu);
return 0;
}
+#ifdef ANDROID
+#ifndef RTLD_DL_SYMENT
+#define RTLD_DL_SYMENT 1
+#endif
+#ifndef RTLD_DL_LINKMAP
+#define RTLD_DL_LINKMAP 2
+#endif
+#endif
+
int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
{
//int dladdr(void *addr, Dl_info *info);
@@ -436,7 +449,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
return (void*)start;
}
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
return NULL;
@@ -451,7 +464,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
return (void*)start;
}
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
return NULL;
@@ -461,14 +474,14 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
// size_t is unsigned
if(nlib>=dl->lib_sz) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
printf_dlsym(LOG_NEVER, "%p\n", NULL);
return NULL;
}
if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
printf_dlsym(LOG_NEVER, "%p\n", (void*)NULL);
return NULL;
@@ -481,7 +494,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol, vername?vername:"(nil)");
printf_log(LOG_DEBUG, " Symbol not found\n");
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
return NULL;
}
@@ -497,7 +510,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, "Self", rsymbol, vername?vername:"(nil)");
printf_log(LOG_DEBUG, " Symbol not found\n");
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
return NULL;
}
@@ -516,14 +529,14 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
// size_t is unsigned
if(nlib>=dl->lib_sz) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_error);
return -1;
}
if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_error);
return -1;
@@ -539,7 +552,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
default:
printf_log(LOG_NONE, "Warning, unsupported call to dlinfo(%p, %d, %p)\n", handle, request, info);
if(!dl->last_error)
- dl->last_error = box_malloc(129);
+ dl->last_error = box_calloc(1, 129);
snprintf(dl->last_error, 129, "unsupported call to dlinfo request:%d\n", request);
}
return -1;
@@ -572,9 +585,6 @@ EXPORT int my__dl_find_object(x64emu_t* emu, void* addr, my_dl_find_object_t* re
return -1;
}
-#define CUSTOM_INIT\
- if(!box64_isglibc234) setNeededLibs(lib, 1, "libc.so.6");
-
// define all standard library functions
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibdrm.c b/src/wrapped/wrappedlibdrm.c
index 01f4967..762d05a 100644
--- a/src/wrapped/wrappedlibdrm.c
+++ b/src/wrapped/wrappedlibdrm.c
@@ -6,13 +6,42 @@
#include "wrappedlibs.h"
+#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
const char* libdrmName = "libdrm.so.2";
#define LIBNAME libdrm
+#define ADDED_FUNCTIONS() \
+
+#include "generated/wrappedlibdrmtypes.h"
+
+#include "wrappercallback.h"
+
+EXPORT void my_drmMsg(x64emu_t* emu, void* fmt, void* b) {
+ myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 1);
+ PREPARE_VALIST;
+ char* buf = NULL;
+ int dummy = vasprintf(&buf, (const char*)fmt, VARARGS);
+ (void)dummy;
+ my->drmMsg(buf);
+ free(buf);
+}
+
+#define CUSTOM_INIT \
+ getMy(lib);
+
+#define CUSTOM_FINI \
+ freeMy();
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibdrm_private.h b/src/wrapped/wrappedlibdrm_private.h
index a368b88..47df162 100644
--- a/src/wrapped/wrappedlibdrm_private.h
+++ b/src/wrapped/wrappedlibdrm_private.h
@@ -28,9 +28,9 @@ GO(drmAuthMagic, iFiu)
//GO(drmClose,
//GO(drmCloseOnce,
//GO(drmCommandNone,
-//GO(drmCommandRead,
-//GO(drmCommandWrite,
-//GO(drmCommandWriteRead,
+GO(drmCommandRead, iFiLpL)
+GO(drmCommandWrite, iFiLpL)
+GO(drmCommandWriteRead, iFiLpL)
//GO(drmCreateContext,
//GO(drmCreateDrawable,
//GO(drmCrtcGetSequence,
@@ -73,12 +73,12 @@ GO(drmGetDevices2, iFupi)
GO(drmGetMagic, iFip)
//GO(drmGetMap,
GO(drmGetNodeTypeFromFd, iFi)
-//GO(drmGetPrimaryDeviceNameFromFd,
+GO(drmGetPrimaryDeviceNameFromFd, pFi)
//GO(drmGetRenderDeviceNameFromFd,
//GO(drmGetReservedContextList,
//GO(drmGetStats,
GO(drmGetVersion, pFi)
-//GO(drmHandleEvent,
+GO(drmHandleEvent, iFip) //warning, p is *drmHandleEvent that needs wrapping, plenty of function pointer there
GO(drmHashCreate, pFv)
GO(drmHashDelete, iFpL)
GO(drmHashDestroy, iFp)
@@ -92,7 +92,7 @@ GO(drmIoctl, iFiLp)
//GO(drmMap,
//GO(drmMapBufs,
//GO(drmMarkBufs,
-//GO(drmModeAddFB,
+GO(drmModeAddFB, iFiuuCCuup)
//GO(drmModeAddFB2,
//GO(drmModeAddFB2WithModifiers,
//GO(drmModeAtomicAddProperty,
@@ -112,9 +112,9 @@ GO(drmIoctl, iFiLp)
//GO(drmModeDestroyPropertyBlob,
//GO(drmModeDetachMode,
//GO(drmModeDirtyFB,
-//GO(drmModeFreeConnector,
-//GO(drmModeFreeCrtc,
-//GO(drmModeFreeEncoder,
+GO(drmModeFreeConnector, vFp)
+GO(drmModeFreeCrtc, vFp)
+GO(drmModeFreeEncoder, vFp)
//GO(drmModeFreeFB,
//GO(drmModeFreeModeInfo,
//GO(drmModeFreeObjectProperties,
@@ -122,31 +122,31 @@ GO(drmIoctl, iFiLp)
//GO(drmModeFreePlaneResources,
//GO(drmModeFreeProperty,
//GO(drmModeFreePropertyBlob,
-//GO(drmModeFreeResources,
-//GO(drmModeGetConnector,
+GO(drmModeFreeResources, vFp)
+GO(drmModeGetConnector, pFiu)
//GO(drmModeGetConnectorCurrent,
-//GO(drmModeGetCrtc,
-//GO(drmModeGetEncoder,
+GO(drmModeGetCrtc, pFiu)
+GO(drmModeGetEncoder, pFiu)
//GO(drmModeGetFB,
//GO(drmModeGetLease,
//GO(drmModeGetPlane,
//GO(drmModeGetPlaneResources,
//GO(drmModeGetProperty,
//GO(drmModeGetPropertyBlob,
-//GO(drmModeGetResources,
+GO(drmModeGetResources, pFi)
//GO(drmModeListLessees,
//GO(drmModeMoveCursor,
//GO(drmModeObjectGetProperties,
//GO(drmModeObjectSetProperty,
-//GO(drmModePageFlip,
+GO(drmModePageFlip, iFiuuup)
//GO(drmModePageFlipTarget,
//GO(drmModeRevokeLease,
-//GO(drmModeRmFB,
-//GO(drmModeSetCrtc,
+GO(drmModeRmFB, iFiu)
+GO(drmModeSetCrtc, iFiuuuupip)
//GO(drmModeSetCursor,
//GO(drmModeSetCursor2,
//GO(drmModeSetPlane,
-//GO(drmMsg,
+GOM(drmMsg, vFEpV)
//GO(drmOpen,
//GO(drmOpenControl,
//GO(drmOpenOnce,
@@ -178,19 +178,20 @@ GO(drmPrimeHandleToFD, iFiuup)
//GO(drmSLLookupNeighbors,
//GO(drmSLNext,
//GO(drmSwitchToContext,
-//GO(drmSyncobjCreate,
-//GO(drmSyncobjDestroy,
-//GO(drmSyncobjExportSyncFile,
-//GO(drmSyncobjFDToHandle,
-//GO(drmSyncobjHandleToFD,
-//GO(drmSyncobjImportSyncFile,
-//GO(drmSyncobjQuery,
-//GO(drmSyncobjReset,
-//GO(drmSyncobjSignal,
-//GO(drmSyncobjTimelineSignal,
-//GO(drmSyncobjTimelineWait,
-//GO(drmSyncobjTransfer,
-//GO(drmSyncobjWait,
+GO(drmSyncobjCreate, iFiup)
+GO(drmSyncobjDestroy, iFiu)
+GO(drmSyncobjExportSyncFile, iFiup)
+GO(drmSyncobjFDToHandle, iFiip)
+GO(drmSyncobjHandleToFD, iFiup)
+GO(drmSyncobjImportSyncFile, iFiui)
+GO(drmSyncobjQuery, iFippu)
+GO(drmSyncobjQuery2, iFippuu)
+GO(drmSyncobjReset, iFipu)
+GO(drmSyncobjSignal, iFipu)
+GO(drmSyncobjTimelineSignal, iFippu)
+GO(drmSyncobjTimelineWait, iFippuIup)
+GO(drmSyncobjTransfer, iFiuUuUu)
+GO(drmSyncobjWait, iFipuIup)
//GO(drmUnlock,
//GO(drmUnmap,
//GO(drmUnmapBufs,
diff --git a/src/wrapped/wrappedlibformw.c b/src/wrapped/wrappedlibformw.c
index b06620c..686aacd 100644
--- a/src/wrapped/wrappedlibformw.c
+++ b/src/wrapped/wrappedlibformw.c
@@ -14,4 +14,7 @@
const char* libformwName = "libformw.so.5";
#define LIBNAME libformw
+#define CUSTOM_INIT \
+ SETALT(myw_); \
+
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibformw6.c b/src/wrapped/wrappedlibformw6.c
new file mode 100644
index 0000000..92e8069
--- /dev/null
+++ b/src/wrapped/wrappedlibformw6.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* libformw6Name = "libformw.so.6";
+#define LIBNAME libformw6
+
+#define CUSTOM_INIT \
+ SETALT(my6_); \
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibformw6_private.h b/src/wrapped/wrappedlibformw6_private.h
new file mode 100644
index 0000000..d204dff
--- /dev/null
+++ b/src/wrapped/wrappedlibformw6_private.h
@@ -0,0 +1,80 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh....
+#endif
+
+//GOM(new_fieldtype, pFPP)
+GO(link_fieldtype, pFpp)
+GO(free_fieldtype, iFp)
+//GOM(set_fieldtype_arg, iFpPPP)
+//GOM(set_fieldtype_choice, iFpPP)
+GO(new_field, pFiiiiii)
+GO(dup_field, pFpii)
+GO(link_field, pFpii)
+GO(free_field, iFp)
+GO(field_info, iFppppppp)
+GO(dynamic_field_info, iFpppp)
+GO(set_max_field, iFpi)
+GO(move_field, iFpii)
+//GO(set_field_type, iFpp,...)
+GO(set_new_page, iFpi)
+GO(set_field_just, iFpi)
+GO(field_just, iFp)
+GO(set_field_fore, iFpL)
+GO(set_field_back, iFpL)
+GO(set_field_pad, iFpi)
+GO(field_pad, iFp)
+GO(set_field_buffer, iFpip)
+GO(set_field_status, iFpi)
+GO(set_field_userptr, iFpp)
+GO(set_field_opts, iFpi)
+GO(field_opts_on, iFpi)
+GO(field_opts_off, iFpi)
+GO(field_fore, LFp)
+GO(field_back, LFp)
+GO(new_page, iFp)
+GO(field_status, iFp)
+GO(field_arg, pFp)
+GO(field_userptr, pFp)
+GO(field_type, pFp)
+GO(field_buffer, pFpi)
+GO(field_opts, iFp)
+GO(new_form, pFp)
+GO(form_fields, pFp)
+GO(current_field, pFp)
+GO(form_win, pFp)
+GO(form_sub, pFp)
+//GOM(form_init, PFp)
+//GOM(form_term, PFp)
+//GOM(field_init, PFp)
+//GOM(field_term, PFp)
+GO(free_form, iFp)
+GO(set_form_fields, iFpp)
+GO(field_count, iFp)
+GO(set_form_win, iFpp)
+GO(set_form_sub, iFpp)
+GO(set_current_field, iFpp)
+GO(unfocus_current_field, iFp)
+GO(field_index, iFp)
+GO(set_form_page, iFpi)
+GO(form_page, iFp)
+GO(scale_form, iFppp)
+//GOM(set_form_init, iFpP)
+//GOM(set_form_term, iFpP)
+//GOM(set_field_init, iFpP)
+//GOM(set_field_term, iFpP)
+GO(post_form, iFp)
+GO(unpost_form, iFp)
+GO(pos_form_cursor, iFp)
+GO(form_driver, iFpi)
+GO(form_driver_w, iFpiu)
+GO(set_form_userptr, iFpp)
+GO(set_form_opts, iFpi)
+GO(form_opts_on, iFpi)
+GO(form_opts_off, iFpi)
+GO(form_request_by_name, iFp)
+GO(form_request_name, pFi)
+GO(form_userptr, pFp)
+GO(form_opts, iFp)
+GO(data_ahead, iFp)
+GO(data_behind, iFp)
+GO(new_form_sp, pFpp)
diff --git a/src/wrapped/wrappedlibgl.c b/src/wrapped/wrappedlibgl.c
index 1d5eb93..513bd77 100644
--- a/src/wrapped/wrappedlibgl.c
+++ b/src/wrapped/wrappedlibgl.c
@@ -33,6 +33,7 @@ EXPORT void* my_glXGetProcAddressARB(x64emu_t* emu, void* name) __attribute__((a
typedef int (*iFi_t)(int);
typedef void (*vFpp_t)(void*, void*);
+typedef void (*vFppi_t)(void*, void*, int);
typedef void*(*pFp_t)(void*);
typedef void (*debugProc_t)(int32_t, int32_t, uint32_t, int32_t, int32_t, void*, void*);
@@ -201,9 +202,15 @@ static int my_glXSwapIntervalMESA_##A(int interval) \
}
SUPER()
#undef GO
+
+static int my_dummy_glXSwapIntervalMESA(int interval)
+{
+ return 5; // GLX_BAD_CONTEXT
+}
+
static void* find_glXSwapIntervalMESA_Fct(void* fct)
{
- if(!fct) return fct;
+ if(!fct) return my_dummy_glXSwapIntervalMESA;
#define GO(A) if(my_glXSwapIntervalMESA_fct_##A == (iFi_t)fct) return my_glXSwapIntervalMESA_##A;
SUPER()
#undef GO
@@ -213,6 +220,34 @@ static void* find_glXSwapIntervalMESA_Fct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for libGL glXSwapIntervalMESA callback\n");
return NULL;
}
+
+// glXSwapIntervalEXT ...
+#define GO(A) \
+static vFppi_t my_glXSwapIntervalEXT_fct_##A = NULL; \
+static void my_glXSwapIntervalEXT_##A(void* dpy, void* drawable, int interval) \
+{ \
+ if (!my_glXSwapIntervalEXT_fct_##A) \
+ return; \
+ my_glXSwapIntervalEXT_fct_##A(dpy, drawable, interval); \
+}
+SUPER()
+#undef GO
+
+static void my_dummy_glXSwapIntervalEXT(void* dpy, void* drawable, int interval) {}
+
+static void* find_glXSwapIntervalEXT_Fct(void* fct)
+{
+ if(!fct) return my_dummy_glXSwapIntervalEXT;
+ #define GO(A) if(my_glXSwapIntervalEXT_fct_##A == (vFppi_t)fct) return my_glXSwapIntervalEXT_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_glXSwapIntervalEXT_fct_##A == 0) {my_glXSwapIntervalEXT_fct_##A = (vFppi_t)fct; return my_glXSwapIntervalEXT_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for libGL glXSwapIntervalEXT callback\n");
+ return NULL;
+}
+
// glProgramCallbackMESA ...
#define GO(A) \
static vFpp_t my_glProgramCallbackMESA_fct_##A = NULL; \
@@ -264,8 +299,29 @@ static void* find_glGetVkProcAddrNV_Fct(void* fct)
#define PRE_INIT if(box64_libGL) {lib->w.lib = dlopen(box64_libGL, RTLD_LAZY | RTLD_GLOBAL); lib->path = strdup(box64_libGL);} else
#define CUSTOM_INIT \
- my_lib = lib; \
- lib->w.priv = dlsym(lib->w.lib, "glXGetProcAddress"); \
+ my_lib = lib; \
+ lib->w.priv = dlsym(lib->w.lib, "glXGetProcAddress"); \
+ void* symb = dlsym(lib->w.lib, "glDebugMessageCallback"); \
+ if(symb) { \
+ k = kh_get(symbolmap, lib->w.mysymbolmap, "glDebugMessageCallback"); \
+ symbol1_t *s = &kh_value(lib->w.mysymbolmap, k); \
+ s->resolved = 1; \
+ s->addr = (uintptr_t)find_glDebugMessageCallback_Fct(symb); \
+ } \
+ symb = dlsym(lib->w.lib, "glXSwapIntervalMESA"); \
+ if(symb) { \
+ k = kh_get(symbolmap, lib->w.mysymbolmap, "glXSwapIntervalMESA"); \
+ symbol1_t *s = &kh_value(lib->w.mysymbolmap, k); \
+ s->resolved = 1; \
+ s->addr = (uintptr_t)find_glXSwapIntervalMESA_Fct(symb); \
+ } \
+ symb = dlsym(lib->w.lib, "glXSwapIntervalEXT"); \
+ if(symb) { \
+ k = kh_get(symbolmap, lib->w.mysymbolmap, "glXSwapIntervalEXT"); \
+ symbol1_t *s = &kh_value(lib->w.mysymbolmap, k); \
+ s->resolved = 1; \
+ s->addr = (uintptr_t)find_glXSwapIntervalEXT_Fct(symb); \
+ } \
#include "wrappedlib_init.h"
@@ -275,6 +331,7 @@ static void* find_glGetVkProcAddrNV_Fct(void* fct)
GO(vFpp_t, glDebugMessageCallbackAMD) \
GO(vFpp_t, glDebugMessageCallbackKHR) \
GO(iFi_t, glXSwapIntervalMESA) \
+ GO(vFppi_t, glXSwapIntervalEXT) \
GO(vFpp_t, glProgramCallbackMESA) \
GO(pFp_t, glGetVkProcAddrNV) \
@@ -297,20 +354,23 @@ gl_wrappers_t* getGLProcWrapper(box64context_t* context, glprocaddress_t procadd
cnt = sizeof(libglsymbolmap)/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, wrappers->glwrappers, libglsymbolmap[i].name, &ret);
- kh_value(wrappers->glwrappers, k) = libglsymbolmap[i].w;
+ kh_value(wrappers->glwrappers, k).w = libglsymbolmap[i].w;
+ kh_value(wrappers->glwrappers, k).resolved = 0;
}
// and the my_ symbols map
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, wrappers->glwrappers, libglmysymbolmap[i].name, &ret);
- kh_value(wrappers->glwrappers, k) = libglmysymbolmap[i].w;
+ kh_value(wrappers->glwrappers, k).w = libglmysymbolmap[i].w;
+ kh_value(wrappers->glwrappers, k).resolved = 0;
}
// my_* map
wrappers->glmymap = kh_init(symbolmap);
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, wrappers->glmymap, libglmysymbolmap[i].name, &ret);
- kh_value(wrappers->glmymap, k) = libglmysymbolmap[i].w;
+ kh_value(wrappers->glmymap, k).w = libglmysymbolmap[i].w;
+ kh_value(wrappers->glmymap, k).resolved = 0;
}
return wrappers;
}
@@ -392,9 +452,14 @@ void* getGLProcAddress(x64emu_t* emu, glprocaddress_t procaddr, const char* rnam
printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname);
return NULL;
}
- const char* constname = kh_key(wrappers->glwrappers, k);
- AddOffsetSymbol(emu->context->maplib, symbol, rname);
- ret = AddBridge(emu->context->system, kh_value(wrappers->glwrappers, k), symbol, 0, constname);
+ symbol1_t* s = &kh_value(wrappers->glwrappers, k);
+ if(!s->resolved) {
+ const char* constname = kh_key(wrappers->glwrappers, k);
+ AddOffsetSymbol(emu->context->maplib, symbol, rname);
+ s->addr = AddBridge(emu->context->system, s->w, symbol, 0, constname);
+ s->resolved = 1;
+ }
+ ret = s->addr;
printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret);
return (void*)ret;
}
diff --git a/src/wrapped/wrappedlibgl_private.h b/src/wrapped/wrappedlibgl_private.h
index c87bb80..b25f26d 100644
--- a/src/wrapped/wrappedlibgl_private.h
+++ b/src/wrapped/wrappedlibgl_private.h
@@ -3046,7 +3046,7 @@ GO(glXWaitForMscOML, iFppIIIppp)
GO(glXWaitForSbcOML, iFppIppp)
//GLX_EXT_swap_control
-GO(glXSwapIntervalEXT,pFppi)
+GOM(glXSwapIntervalEXT,vFppi)
//GLX_EXT_swap_control_tear
//nothing
@@ -3407,6 +3407,16 @@ GO(glClipPlanef,vFup)
GO(glFrustumf,vFffffff)
GO(glGetClipPlanef,vFup)
GO(glOrthof,vFffffff)
+GO(glActiveShaderProgramEXT, vFuu)
+GO(glBindProgramPipelineEXT, vFu)
+GO(glCreateShaderProgramvEXT, uFilp)
+GO(glDeleteProgramPipelinesEXT, vFilu)
+GO(glGenProgramPipelinesEXT, vFlp)
+GO(glGetProgramPipelineInfoLogEXT, vFulpp)
+GO(glGetProgramPipelineivEXT, vFuip)
+GO(glIsProgramPipelineEXT, iFu)
+GO(glUseProgramStagesEXT, vFuuu)
+GO(glValidateProgramPipelineEXT, vFu)
// GL_EXT_window_rectangles
GO(glWindowRectanglesEXT, vFuip)
diff --git a/src/wrapped/wrappedlibm.c b/src/wrapped/wrappedlibm.c
index 43bdf5c..670ce37 100644
--- a/src/wrapped/wrappedlibm.c
+++ b/src/wrapped/wrappedlibm.c
@@ -1,10 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#define _GNU_SOURCE /* See feature_test_macros(7) */
+#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include <complex.h>
#include <math.h>
+#include <fenv.h>
#include "wrappedlibs.h"
@@ -13,8 +14,16 @@
#include "librarian/library_private.h"
#include "x64emu.h"
#include "debug.h"
+#include "emu/x64emu_private.h"
+
+const char* libmName =
+#ifdef ANDROID
+ "libm.so"
+#else
+ "libm.so.6"
+#endif
+ ;
-const char* libmName = "libm.so.6";
#define LIBNAME libm
static library_t* my_lib = NULL;
@@ -83,12 +92,114 @@ F2D(fmod)
#undef F1F
#undef FINITE
+// x86-64
+// FE_TONEAREST 0x0
+// FE_DOWNWARD 0x400
+// FE_UPWARD 0x800
+// FE_TOWARDZERO 0xc00
+
+#if defined(__aarch64__)
+// AArch64
+// #define FE_TONEAREST 0x000000
+// #define FE_DOWNWARD 0x800000
+// #define FE_UPWARD 0x400000
+// #define FE_TOWARDZERO 0xc00000
+#define TO_NATIVE(round) ((round == 0x400 ? 0x800 : (round == 0x800 ? 0x400 : round)) << 12)
+#elif defined(__riscv)
+// RISC-V
+// #define FE_TONEAREST 0x0
+// #define FE_DOWNWARD 0x2
+// #define FE_UPWARD 0x3
+// #define FE_TOWARDZERO 0x1
+#define TO_NATIVE(round) ((round == 0xc00 ? 0x400 : (round == 0x0 ? round : round + 0x400)) >> 10)
+#elif defined(__loongarch64)
+// LOONGARCH
+// FE_TONEAREST 0x000
+// FE_DOWNWARD 0x300
+// FE_UPWARD 0x200
+// FE_TOWARDZERO 0x100
+#define TO_NATIVE(round) ((round == 0x400 ? 0xc00 : (round == 0xc00 ? 0x400 : round)) >> 2)
+#elif defined(__powerpc64__)
+// PPC
+// FE_TONEAREST 0x0
+// FE_DOWNWARD 0x3
+// FE_UPWARD 0x2
+// FE_TOWARDZERO 0x1
+#define TO_NATIVE(round) ((round == 0x400 ? 0xc00 : (round == 0xc00 ? 0x400 : round)) >> 10)
+#elif defined(__x86_64__)
+#define TO_NATIVE(round) round
+#else
+#error Unknown architecture!
+#endif
+
+// See https://github.com/bminor/glibc/blob/master/sysdeps/x86_64/fpu/fesetround.c
+EXPORT int my_fesetround(x64emu_t* emu, int round)
+{
+ if (box64_sync_rounding) {
+ if ((round & ~0xc00) != 0)
+ // round is not valid.
+ return 1;
+
+ emu->cw.x16 &= ~0xc00;
+ emu->cw.x16 |= round;
+
+ emu->mxcsr.x32 &= ~0x6000;
+ emu->mxcsr.x32 |= round << 3;
+
+ return 0;
+ } else {
+ return fesetround(round);
+ }
+}
+
+// See https://github.com/bminor/glibc/blob/master/sysdeps/x86_64/fpu/fegetround.c
+EXPORT int my_fegetround(x64emu_t* emu)
+{
+ if (box64_sync_rounding) {
+ return emu->cw.x16 & 0xc00;
+ } else {
+ return fegetround();
+ }
+}
+
+#define FROUND(N, T, R) \
+ EXPORT R my_##N(x64emu_t* emu, T val) \
+ { \
+ if (box64_sync_rounding) { \
+ int round = emu->cw.x16 & 0xc00; \
+ fesetround(TO_NATIVE(round)); \
+ } \
+ return N(val); \
+ }
-#define CUSTOM_INIT \
+FROUND(rint, double, double)
+FROUND(rintf, float, float)
+FROUND(lrint, double, int)
+FROUND(lrintf, float, int)
+FROUND(llrint, double, long)
+FROUND(llrintf, float, long)
+FROUND(nearbyint, double, double)
+FROUND(nearbyintf, float, float)
+#ifdef HAVE_LD80BITS
+FROUND(llrintl, long double, long double)
+#else
+EXPORT double my_llrintl(x64emu_t* emu, double val)
+{
+ if (box64_sync_rounding) {
+ int round = emu->cw.x16 & 0xc00;
+ fesetround(TO_NATIVE(round));
+ }
+ return llrint(val);
+}
+#endif
+
+#undef FROUND
+#undef TO_NATIVE
+
+#define CUSTOM_INIT \
my_lib = lib;
#define CUSTOM_FINI \
my_lib = NULL;
#include "wrappedlib_init.h"
-
diff --git a/src/wrapped/wrappedlibm_private.h b/src/wrapped/wrappedlibm_private.h
index 16a2f0e..d6b289c 100644
--- a/src/wrapped/wrappedlibm_private.h
+++ b/src/wrapped/wrappedlibm_private.h
@@ -202,12 +202,12 @@ GO(feenableexcept, iFi)
GO(fegetenv, iFp)
GO(fegetexcept, iFv)
GO(fegetexceptflag, iFpi)
-GO(fegetround, iFv)
+GOM(fegetround, iFEv)
GO(feholdexcept, iFp)
GO(feraiseexcept, iFi)
GO(fesetenv, iFp)
GO(fesetexceptflag, iFpi)
-GO(fesetround, iFi)
+GOM(fesetround, iFEi)
GO(fetestexcept, iFi)
GO(feupdateenv, iFp)
GOW(finite, iFd)
@@ -307,12 +307,12 @@ GO2(lgammal_r, KFKp, lgamma_r)
GOW(lgamma_r, dFdp)
// __lgamma_r_finite
DATAV(_LIB_VERSION, 8)
-GOW(llrint, IFd)
-GOW(llrintf, IFf)
+GOWM(llrint, IFEd)
+GOWM(llrintf, IFEf)
#ifdef HAVE_LD80BITS
-GOW(llrintl, IFD)
+GOWM(llrintl, IFED)
#else
-GO2(llrintl, IFK, llrint)
+GOWM(llrintl, IFEK)
#endif
GOW(llround, IFd)
GOW(llroundf, IFf)
@@ -346,8 +346,8 @@ GOW(logl, DFD)
#else
GO2(logl, KFK, log)
#endif
-GOW(lrint, iFd)
-GOW(lrintf, iFf)
+GOWM(lrint, iFEd)
+GOWM(lrintf, iFEf)
// lrintl // Weak
GOW(lround, iFd)
GOW(lroundf, iFf)
@@ -359,8 +359,8 @@ GOW(modff, fFfp)
GOW(nan, dFp)
GOW(nanf, fFp)
// nanl // Weak
-GOW(nearbyint, dFd)
-GOW(nearbyintf, fFf)
+GOWM(nearbyint, dFEd)
+GOWM(nearbyintf, fFEf)
// nearbyintl // Weak
GOW(nextafter, dFdd)
GOW(nextafterf, fFff)
@@ -392,8 +392,8 @@ GOW(remainderf, fFff)
GOW(remquo, dFddp)
GOW(remquof, fFffp)
// remquol // Weak
-GOW(rint, dFd)
-GOW(rintf, fFf)
+GOWM(rint, dFEd)
+GOWM(rintf, fFEf)
// rintl // Weak
GOW(round, dFd)
GOW(roundf, fFf)
diff --git a/src/wrapped/wrappedlibogg_private.h b/src/wrapped/wrappedlibogg_private.h
index 3440cc2..1f1a96f 100644
--- a/src/wrapped/wrappedlibogg_private.h
+++ b/src/wrapped/wrappedlibogg_private.h
@@ -47,8 +47,8 @@ GO(ogg_page_checksum_set, iFp)
GO(ogg_page_continued, iFp)
GO(ogg_page_eos, iFp)
GO(ogg_page_granulepos, IFp)
-//GO(ogg_page_packets,
-//GO(ogg_page_pageno,
+GO(ogg_page_packets, iFp)
+GO(ogg_page_pageno, lFp)
GO(ogg_page_serialno, iFp)
//GO(ogg_page_version,
//GO(ogg_stream_check,
diff --git a/src/wrapped/wrappedlibpcre.c b/src/wrapped/wrappedlibpcre.c
index 9d3b606..98581aa 100644
--- a/src/wrapped/wrappedlibpcre.c
+++ b/src/wrapped/wrappedlibpcre.c
@@ -20,7 +20,10 @@ typedef void (*pcre_free_t)(void *);
EXPORT uintptr_t my_pcre_free;
void wrapped_pcre_free(void* p) {
- RunFunctionFmt(my_pcre_free, "p", p);
+ if(my_pcre_free)
+ RunFunctionFmt(my_pcre_free, "p", p);
+ else
+ box_free(p);
}
EXPORT pcre_free_t pcre_free = wrapped_pcre_free;
diff --git a/src/wrapped/wrappedlibpthread_private.h b/src/wrapped/wrappedlibpthread_private.h
index c0fd055..ca356e3 100644
--- a/src/wrapped/wrappedlibpthread_private.h
+++ b/src/wrapped/wrappedlibpthread_private.h
@@ -135,7 +135,7 @@ GO(pthread_getname_np, iFppL)
GO(pthread_join, iFLp)
GOM(__pthread_key_create, iFEpp)
GOM(pthread_key_create, iFEpp)
-GO(pthread_key_delete, iFL)
+GOM(pthread_key_delete, iFEL)
GO2(pthread_kill@GLIBC_2.2.5, iFEpi, my_pthread_kill_old)
GOM(pthread_kill, iFEpi)
GO(pthread_kill_other_threads_np, vFv)
diff --git a/src/wrapped/wrappedlibrt.c b/src/wrapped/wrappedlibrt.c
index f89d353..f54f62b 100644
--- a/src/wrapped/wrappedlibrt.c
+++ b/src/wrapped/wrappedlibrt.c
@@ -4,6 +4,11 @@
#include <string.h>
#include <dlfcn.h>
#include <signal.h>
+#ifndef ANDROID
+#include <aio.h>
+#else
+#include <errno.h>
+#endif
#include "wrappedlibs.h"
@@ -29,6 +34,10 @@
const char* librtName = "librt.so.1";
#define LIBNAME librt
+#include "generated/wrappedlibrttypes.h"
+
+#include "wrappercallback.h"
+
#define SUPER() \
GO(0) \
GO(1) \
@@ -72,5 +81,84 @@ EXPORT int my_timer_create(x64emu_t* emu, uint32_t clockid, void* sevp, timer_t*
return timer_create(clockid, &sevent, timerid);
}
+#ifndef ANDROID
+EXPORT int my_aio_cancel(x64emu_t emu, int fd, struct aiocb* aiocbp)
+{
+ if(aiocbp && aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
+ aiocbp->aio_sigevent.sigev_notify_function = findsigev_notifyFct(aiocbp->aio_sigevent.sigev_notify_function);
+ return my->aio_cancel(fd, aiocbp);
+}
+EXPORT int my_aio_read(x64emu_t emu, struct aiocb* aiocbp)
+{
+ if(aiocbp && aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
+ aiocbp->aio_sigevent.sigev_notify_function = findsigev_notifyFct(aiocbp->aio_sigevent.sigev_notify_function);
+ return my->aio_read(aiocbp);
+}
+EXPORT int my_aio_read64(x64emu_t emu, struct aiocb* aiocbp)
+{
+ if(aiocbp && aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
+ aiocbp->aio_sigevent.sigev_notify_function = findsigev_notifyFct(aiocbp->aio_sigevent.sigev_notify_function);
+ return my->aio_read64(aiocbp);
+}
+EXPORT int my_aio_write(x64emu_t emu, struct aiocb* aiocbp)
+{
+ if(aiocbp && aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
+ aiocbp->aio_sigevent.sigev_notify_function = findsigev_notifyFct(aiocbp->aio_sigevent.sigev_notify_function);
+ return my->aio_write(aiocbp);
+}
+EXPORT int my_aio_write64(x64emu_t emu, struct aiocb* aiocbp)
+{
+ if(aiocbp && aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD)
+ aiocbp->aio_sigevent.sigev_notify_function = findsigev_notifyFct(aiocbp->aio_sigevent.sigev_notify_function);
+ return my->aio_write64(aiocbp);
+}
+EXPORT int mylio_listio(x64emu_t* emu, int mode, struct aiocb* list[], int nent, struct sigevent* sig)
+{
+ struct sigevent sevent;
+ if(sig) {
+ memcpy(&sevent, sig, sizeof(sevent));
+ if(sevent.sigev_notify == SIGEV_THREAD)
+ sevent.sigev_notify_function = findsigev_notifyFct(sevent.sigev_notify_function);
+ }
+ return my->lio_listio(mode, list, nent, sig?(&sevent):sig);
+}
+#else
+EXPORT int my_aio_cancel(x64emu_t emu, int fd, void* aiocbp)
+{
+ errno = ENOSYS;
+ return -1;
+}
+EXPORT int my_aio_read(x64emu_t emu, void* aiocbp)
+{
+ errno = ENOSYS;
+ return -1;
+}
+EXPORT int my_aio_read64(x64emu_t emu, void* aiocbp)
+{
+ errno = ENOSYS;
+ return -1;
+}
+EXPORT int my_aio_write(x64emu_t emu, void* aiocbp)
+{
+ errno = ENOSYS;
+ return -1;
+}
+EXPORT int my_aio_write64(x64emu_t emu, void* aiocbp)
+{
+ errno = ENOSYS;
+ return -1;
+}
+EXPORT int mylio_listio(x64emu_t* emu, int mode, void* list[], int nent, struct sigevent* sig)
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+#define CUSTOM_INIT \
+ getMy(lib);
+
+#define CUSTOM_FINI \
+ freeMy();
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibrt_private.h b/src/wrapped/wrappedlibrt_private.h
index 75eb3fa..0f90829 100644
--- a/src/wrapped/wrappedlibrt_private.h
+++ b/src/wrapped/wrappedlibrt_private.h
@@ -7,27 +7,27 @@
// time_t is uint32?
// mqd_t is int
-GO(aio_cancel, iFip)
+GOM(aio_cancel, iFEip)
// aio_cancel64
GO(aio_error, iFp)
GO(aio_error64, iFp)
GO(aio_fsync, iFip)
GO(aio_fsync64, iFip)
GO(aio_init, vFp)
-GO(aio_read, iFp)
-GO(aio_read64, iFp)
+GOM(aio_read, iFEp)
+GOM(aio_read64, iFEp)
GO(aio_return, lFp)
GO(aio_return64, lFp)
GO(aio_suspend, iFpip)
GO(aio_suspend64, iFpip)
-GO(aio_write, iFp)
-GO(aio_write64, iFp)
+GOM(aio_write, iFEp)
+GOM(aio_write64, iFEp)
GO(clock_getcpuclockid, iFup)
GO(clock_getres, iFup)
GO(clock_gettime, iFup)
GO(clock_nanosleep, iFuipp)
GO(clock_settime, iFup)
-GO(lio_listio, iFippip)
+GOM(lio_listio, iFEipip)
// lio_listio64
GO(mq_close, iFi)
GO(mq_getattr, iFip)
diff --git a/src/wrapped/wrappedlibsndfile.c b/src/wrapped/wrappedlibsndfile.c
index bbb11b5..af3bad5 100644
--- a/src/wrapped/wrappedlibsndfile.c
+++ b/src/wrapped/wrappedlibsndfile.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libsndfileName = "libsndfile.so.1";
+#ifdef ANDROID
+ const char* libsndfileName = "libsndfile.so";
+#else
+ const char* libsndfileName = "libsndfile.so.1";
+#endif
+
#define LIBNAME libsndfile
#define ADDED_FUNCTIONS() \
diff --git a/src/wrapped/wrappedlibusb1.c b/src/wrapped/wrappedlibusb1.c
index c5fea90..38dd589 100644
--- a/src/wrapped/wrappedlibusb1.c
+++ b/src/wrapped/wrappedlibusb1.c
@@ -18,7 +18,12 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
-const char* libusb1Name = "libusb-1.0.so.0";
+#ifdef ANDROID
+ const char* libusb1Name = "libusb-1.0.so";
+#else
+ const char* libusb1Name = "libusb-1.0.so.0";
+#endif
+
#define LIBNAME libusb1
#define ADDED_FUNCTIONS() \
diff --git a/src/wrapped/wrappedlibva_private.h b/src/wrapped/wrappedlibva_private.h
index cba8dc0..c859203 100644
--- a/src/wrapped/wrappedlibva_private.h
+++ b/src/wrapped/wrappedlibva_private.h
@@ -2,7 +2,7 @@
#error meh!
#endif
-//GO(vaAcquireBufferHandle,
+GO(vaAcquireBufferHandle, iFpup)
//GO(vaAssociateSubpicture,
//GO(vaAttachProtectedSession,
GO(vaBeginPicture, iFpup)
@@ -74,10 +74,10 @@ GO(vaQueryVendorString, pFp)
//GO(vaQueryVideoProcFilterCaps,
//GO(vaQueryVideoProcFilters,
GO(vaQueryVideoProcPipelineCaps, iFpupup)
-//GO(vaReleaseBufferHandle,
+GO(vaReleaseBufferHandle, iFpu)
GO(vaRenderPicture, iFpupi)
//GO(vaSetDisplayAttributes,
-//GO(vaSetDriverName,
+GO(vaSetDriverName, iFpp)
GOM(vaSetErrorCallback, pFEppp)
//GO(vaSetImagePalette,
GOM(vaSetInfoCallback, pFEppp)
diff --git a/src/wrapped/wrappedlibvorbis.c b/src/wrapped/wrappedlibvorbis.c
index 7449582..0807e5b 100644
--- a/src/wrapped/wrappedlibvorbis.c
+++ b/src/wrapped/wrappedlibvorbis.c
@@ -17,8 +17,12 @@
#include "librarian.h"
#include "myalign.h"
+#ifdef ANDROID
+ const char* libvorbisName = "libvorbis.so";
+#else
+ const char* libvorbisName = "libvorbis.so.0";
+#endif
-const char* libvorbisName = "libvorbis.so.0";
#define LIBNAME libvorbis
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibx11.c b/src/wrapped/wrappedlibx11.c
index 0ee5d08..70b8cb8 100644
--- a/src/wrapped/wrappedlibx11.c
+++ b/src/wrapped/wrappedlibx11.c
@@ -17,7 +17,12 @@
#include "emu/x64emu_private.h"
#include "myalign.h"
-const char* libx11Name = "libX11.so.6";
+#ifdef ANDROID
+ const char* libx11Name = "libX11.so";
+#else
+ const char* libx11Name = "libX11.so.6";
+#endif
+
#define LIBNAME libx11
typedef int (*XErrorHandler)(void *, void *);
diff --git a/src/wrapped/wrappedlibxau.c b/src/wrapped/wrappedlibxau.c
index 7537eb0..b03e75e 100644
--- a/src/wrapped/wrappedlibxau.c
+++ b/src/wrapped/wrappedlibxau.c
@@ -11,7 +11,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxauName = "libXau.so.6";
+#ifdef ANDROID
+ const char* libxauName = "libXau.so";
+#else
+ const char* libxauName = "libXau.so.6";
+#endif
+
#define LIBNAME libxau
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcb.c b/src/wrapped/wrappedlibxcb.c
index d3798d4..37db2ea 100644
--- a/src/wrapped/wrappedlibxcb.c
+++ b/src/wrapped/wrappedlibxcb.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbName = "libxcb.so.1";
+#ifdef ANDROID
+ const char* libxcbName = "libxcb.so";
+#else
+ const char* libxcbName = "libxcb.so.1";
+#endif
+
#define LIBNAME libxcb
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcb_private.h b/src/wrapped/wrappedlibxcb_private.h
index 10988e2..1ae141d 100644
--- a/src/wrapped/wrappedlibxcb_private.h
+++ b/src/wrapped/wrappedlibxcb_private.h
@@ -207,7 +207,7 @@ GO(xcb_free_cursor, pFpp)
GO(xcb_free_gc, pFpu)
//GO(xcb_free_gc_checked,
GO(xcb_free_pixmap, pFpu)
-//GO(xcb_free_pixmap_checked,
+GO(xcb_free_pixmap_checked, pFpu)
//GO(xcb_gcontext_end,
//GO(xcb_gcontext_next,
GO(xcb_generate_id, uFp)
@@ -462,7 +462,7 @@ GO(xcb_popcount, iFu)
GO(xcb_prefetch_extension_data, vFpp)
GO(xcb_prefetch_maximum_request_length, vFp)
GO(xcb_put_image, pFpCuuWWwwCCup)
-//GO(xcb_put_image_checked,
+GO(xcb_put_image_checked, pFpCuuWWwwCCup)
//GO(xcb_put_image_data,
//GO(xcb_put_image_data_end,
//GO(xcb_put_image_data_length,
@@ -491,9 +491,9 @@ GO(xcb_put_image, pFpCuuWWwwCCup)
//GO(xcb_query_font_reply,
//GO(xcb_query_font_sizeof,
//GO(xcb_query_font_unchecked,
-//GO(xcb_query_keymap,
-//GO(xcb_query_keymap_reply,
-//GO(xcb_query_keymap_unchecked,
+GO(xcb_query_keymap, pFpp)
+GO(xcb_query_keymap_reply, pFpup)
+GO(xcb_query_keymap_unchecked, pFpp)
GO(xcb_query_pointer, pFpu)
GO(xcb_query_pointer_reply, pFpup)
//GO(xcb_query_pointer_unchecked,
diff --git a/src/wrapped/wrappedlibxcbdri3.c b/src/wrapped/wrappedlibxcbdri3.c
index a0a8542..b351dbe 100644
--- a/src/wrapped/wrappedlibxcbdri3.c
+++ b/src/wrapped/wrappedlibxcbdri3.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbdri3Name = "libxcb-dri3.so.0";
+#ifdef ANDROID
+ const char* libxcbdri3Name = "libxcb-dri3.so";
+#else
+ const char* libxcbdri3Name = "libxcb-dri3.so.0";
+#endif
+
#define LIBNAME libxcbdri3
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbglx.c b/src/wrapped/wrappedlibxcbglx.c
index 5066826..806c58d 100644
--- a/src/wrapped/wrappedlibxcbglx.c
+++ b/src/wrapped/wrappedlibxcbglx.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbglxName = "libxcb-glx.so.0";
+#ifdef ANDROID
+ const char* libxcbglxName = "libxcb-glx.so";
+#else
+ const char* libxcbglxName = "libxcb-glx.so.0";
+#endif
+
#define LIBNAME libxcbglx
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbicccm.c b/src/wrapped/wrappedlibxcbicccm.c
index 5ff0c45..29c9b55 100644
--- a/src/wrapped/wrappedlibxcbicccm.c
+++ b/src/wrapped/wrappedlibxcbicccm.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbicccmName = "libxcb-icccm.so.4";
+#ifdef ANDROID
+ const char* libxcbicccmName = "libxcb-icccm.so";
+#else
+ const char* libxcbicccmName = "libxcb-icccm.so.4";
+#endif
+
#define LIBNAME libxcbicccm
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbimage.c b/src/wrapped/wrappedlibxcbimage.c
index 906e5eb..6ef51ed 100644
--- a/src/wrapped/wrappedlibxcbimage.c
+++ b/src/wrapped/wrappedlibxcbimage.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbimageName = "libxcb-image.so.0";
+#ifdef ANDROID
+ const char* libxcbimageName = "libxcb-image.so";
+#else
+ const char* libxcbimageName = "libxcb-image.so.0";
+#endif
+
#define LIBNAME libxcbimage
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbkeysyms.c b/src/wrapped/wrappedlibxcbkeysyms.c
index 909c904..72c0022 100644
--- a/src/wrapped/wrappedlibxcbkeysyms.c
+++ b/src/wrapped/wrappedlibxcbkeysyms.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbkeysymsName = "libxcb-keysyms.so.1";
+#ifdef ANDROID
+ const char* libxcbkeysymsName = "libxcb-keysyms.so";
+#else
+ const char* libxcbkeysymsName = "libxcb-keysyms.so.1";
+#endif
+
#define LIBNAME libxcbkeysyms
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbpresent.c b/src/wrapped/wrappedlibxcbpresent.c
index f8293d5..4f63285 100644
--- a/src/wrapped/wrappedlibxcbpresent.c
+++ b/src/wrapped/wrappedlibxcbpresent.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbpresentName = "libxcb-present.so.0";
+#ifdef ANDROID
+ const char* libxcbpresentName = "libxcb-present.so";
+#else
+ const char* libxcbpresentName = "libxcb-present.so.0";
+#endif
+
#define LIBNAME libxcbpresent
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbrandr.c b/src/wrapped/wrappedlibxcbrandr.c
index 0b4387e..d4c8cbb 100644
--- a/src/wrapped/wrappedlibxcbrandr.c
+++ b/src/wrapped/wrappedlibxcbrandr.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbrandrName = "libxcb-randr.so.0";
+#ifdef ANDROID
+ const char* libxcbrandrName = "libxcb-randr.so";
+#else
+ const char* libxcbrandrName = "libxcb-randr.so.0";
+#endif
+
#define LIBNAME libxcbrandr
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbrandr_private.h b/src/wrapped/wrappedlibxcbrandr_private.h
index 47a9c4c..88b7aa1 100644
--- a/src/wrapped/wrappedlibxcbrandr_private.h
+++ b/src/wrapped/wrappedlibxcbrandr_private.h
@@ -156,15 +156,15 @@ GO(xcb_randr_get_output_property_reply, pFpup)
//GO(xcb_randr_get_providers_reply,
//GO(xcb_randr_get_providers_sizeof,
//GO(xcb_randr_get_providers_unchecked,
-//GO(xcb_randr_get_screen_info,
-//GO(xcb_randr_get_screen_info_rates_iterator,
-//GO(xcb_randr_get_screen_info_rates_length,
-//GO(xcb_randr_get_screen_info_reply,
+GO(xcb_randr_get_screen_info, pFppu)
+GO(xcb_randr_get_screen_info_rates_iterator, pFpp)
+GO(xcb_randr_get_screen_info_rates_length, iFp)
+GO(xcb_randr_get_screen_info_reply, pFpup)
//GO(xcb_randr_get_screen_info_sizeof,
-//GO(xcb_randr_get_screen_info_sizes,
-//GO(xcb_randr_get_screen_info_sizes_iterator,
-//GO(xcb_randr_get_screen_info_sizes_length,
-//GO(xcb_randr_get_screen_info_unchecked,
+GO(xcb_randr_get_screen_info_sizes, pFp)
+GO(xcb_randr_get_screen_info_sizes_iterator, pFpp)
+GO(xcb_randr_get_screen_info_sizes_length, iFp)
+GO(xcb_randr_get_screen_info_unchecked, pFppu)
GO(xcb_randr_get_screen_resources, pFppu)
//GO(xcb_randr_get_screen_resources_crtcs,
//GO(xcb_randr_get_screen_resources_crtcs_end,
diff --git a/src/wrapped/wrappedlibxcbrender.c b/src/wrapped/wrappedlibxcbrender.c
index 545fbf4..5deeed1 100644
--- a/src/wrapped/wrappedlibxcbrender.c
+++ b/src/wrapped/wrappedlibxcbrender.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbrenderName = "libxcb-render.so.0";
+#ifdef ANDROID
+ const char* libxcbrenderName = "libxcb-render.so";
+#else
+ const char* libxcbrenderName = "libxcb-render.so.0";
+#endif
+
#define LIBNAME libxcbrender
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbrenderutil.c b/src/wrapped/wrappedlibxcbrenderutil.c
index a95801b..6a1f7d8 100644
--- a/src/wrapped/wrappedlibxcbrenderutil.c
+++ b/src/wrapped/wrappedlibxcbrenderutil.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbrenderutilName = "libxcb-render-util.so.0";
+#ifdef ANDROID
+ const char* libxcbrenderutilName = "libxcb-render-util.so";
+#else
+ const char* libxcbrenderutilName = "libxcb-render-util.so.0";
+#endif
+
#define LIBNAME libxcbrenderutil
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbshape.c b/src/wrapped/wrappedlibxcbshape.c
index 3dc9c69..f1eb4e8 100644
--- a/src/wrapped/wrappedlibxcbshape.c
+++ b/src/wrapped/wrappedlibxcbshape.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbshapeName = "libxcb-shape.so.0";
+#ifdef ANDROID
+ const char* libxcbshapeName = "libxcb-shape.so";
+#else
+ const char* libxcbshapeName = "libxcb-shape.so.0";
+#endif
+
#define LIBNAME libxcbshape
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbshm.c b/src/wrapped/wrappedlibxcbshm.c
index 218304c..886d2aa 100644
--- a/src/wrapped/wrappedlibxcbshm.c
+++ b/src/wrapped/wrappedlibxcbshm.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbshmName = "libxcb-shm.so.0";
+#ifdef ANDROID
+ const char* libxcbshmName = "libxcb-shm.so";
+#else
+ const char* libxcbshmName = "libxcb-shm.so.0";
+#endif
+
#define LIBNAME libxcbshm
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbsync.c b/src/wrapped/wrappedlibxcbsync.c
index ee470e8..81e4687 100644
--- a/src/wrapped/wrappedlibxcbsync.c
+++ b/src/wrapped/wrappedlibxcbsync.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbsyncName = "libxcb-sync.so.1";
+#ifdef ANDROID
+ const char* libxcbsyncName = "libxcb-sync.so";
+#else
+ const char* libxcbsyncName = "libxcb-sync.so.1";
+#endif
+
#define LIBNAME libxcbsync
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbutil.c b/src/wrapped/wrappedlibxcbutil.c
index b258858..943d8b9 100644
--- a/src/wrapped/wrappedlibxcbutil.c
+++ b/src/wrapped/wrappedlibxcbutil.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbutilName = "libxcb-util.so.1";
+#ifdef ANDROID
+ const char* libxcbutilName = "libxcb-util.so";
+#else
+ const char* libxcbutilName = "libxcb-util.so.1";
+#endif
+
#define LIBNAME libxcbutil
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbxfixes.c b/src/wrapped/wrappedlibxcbxfixes.c
index e41c3b8..ac95078 100644
--- a/src/wrapped/wrappedlibxcbxfixes.c
+++ b/src/wrapped/wrappedlibxcbxfixes.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbxfixesName = "libxcb-xfixes.so.0";
+#ifdef ANDROID
+ const char* libxcbxfixesName = "libxcb-xfixes.so";
+#else
+ const char* libxcbxfixesName = "libxcb-xfixes.so.0";
+#endif
+
#define LIBNAME libxcbxfixes
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbxinerama.c b/src/wrapped/wrappedlibxcbxinerama.c
index c129e6b..856d7e2 100644
--- a/src/wrapped/wrappedlibxcbxinerama.c
+++ b/src/wrapped/wrappedlibxcbxinerama.c
@@ -17,7 +17,11 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbxineramaName = "libxcb-xinerama.so.0";
+#ifdef ANDROID
+ const char* libxcbxineramaName = "libxcb-xinerama.so";
+#else
+ const char* libxcbxineramaName = "libxcb-xinerama.so.0";
+#endif
#define LIBNAME libxcbxinerama
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbxkb.c b/src/wrapped/wrappedlibxcbxkb.c
index 0f0f983..cc7672b 100644
--- a/src/wrapped/wrappedlibxcbxkb.c
+++ b/src/wrapped/wrappedlibxcbxkb.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbxkbName = "libxcb-xkb.so.1";
+#ifdef ANDROID
+ const char* libxcbxkbName = "libxcb-xkb.so";
+#else
+ const char* libxcbxkbName = "libxcb-xkb.so.1";
+#endif
+
#define LIBNAME libxcbxkb
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcbxtest.c b/src/wrapped/wrappedlibxcbxtest.c
index b08fb35..211efb4 100644
--- a/src/wrapped/wrappedlibxcbxtest.c
+++ b/src/wrapped/wrappedlibxcbxtest.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxcbxtestName = "libxcb-xtest.so.0";
+#ifdef ANDROID
+ const char* libxcbxtestName = "libxcb-xtest.so";
+#else
+ const char* libxcbxtestName = "libxcb-xtest.so.0";
+#endif
+
#define LIBNAME libxcbxtest
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcomposite.c b/src/wrapped/wrappedlibxcomposite.c
index bb0394b..0521f93 100644
--- a/src/wrapped/wrappedlibxcomposite.c
+++ b/src/wrapped/wrappedlibxcomposite.c
@@ -12,7 +12,12 @@
#include "x64emu.h"
#include "debug.h"
-const char* libxcompositeName = "libXcomposite.so.1";
+#ifdef ANDROID
+ const char* libxcompositeName = "libXcomposite.so";
+#else
+ const char* libxcompositeName = "libXcomposite.so.1";
+#endif
+
#define LIBNAME libxcomposite
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxcursor.c b/src/wrapped/wrappedlibxcursor.c
index 749d2a0..be87d56 100644
--- a/src/wrapped/wrappedlibxcursor.c
+++ b/src/wrapped/wrappedlibxcursor.c
@@ -11,7 +11,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxcursorName = "libXcursor.so.1";
+#ifdef ANDROID
+ const char* libxcursorName = "libXcursor.so";
+#else
+ const char* libxcursorName = "libXcursor.so.1";
+#endif
+
#define LIBNAME libxcursor
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxdamage.c b/src/wrapped/wrappedlibxdamage.c
index 6f10e7f..8637f2a 100644
--- a/src/wrapped/wrappedlibxdamage.c
+++ b/src/wrapped/wrappedlibxdamage.c
@@ -12,7 +12,12 @@
#include "x64emu.h"
#include "debug.h"
-const char* libxdamageName = "libXdamage.so.1";
+#ifdef ANDROID
+ const char* libxdamageName = "libXdamage.so";
+#else
+ const char* libxdamageName = "libXdamage.so.1";
+#endif
+
#define LIBNAME libxdamage
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxdmcp.c b/src/wrapped/wrappedlibxdmcp.c
index c320caa..39a47d0 100644
--- a/src/wrapped/wrappedlibxdmcp.c
+++ b/src/wrapped/wrappedlibxdmcp.c
@@ -11,7 +11,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxdmcpName = "libXdmcp.so.6";
+#ifdef ANDROID
+ const char* libxdmcpName = "libXdmcp.so";
+#else
+ const char* libxdmcpName = "libXdmcp.so.6";
+#endif
+
#define LIBNAME libxdmcp
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxext.c b/src/wrapped/wrappedlibxext.c
index 245b65c..06088a8 100644
--- a/src/wrapped/wrappedlibxext.c
+++ b/src/wrapped/wrappedlibxext.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxextName = "libXext.so.6";
+#ifdef ANDROID
+ const char* libxextName = "libXext.so";
+#else
+ const char* libxextName = "libXext.so.6";
+#endif
+
#define LIBNAME libxext
typedef struct _XImage XImage;
@@ -385,14 +390,25 @@ EXPORT void* my_XextAddDisplay(x64emu_t* emu, void* extinfo, void* dpy, void* ex
return ret;
}
-#define CUSTOM_INIT \
- getMy(lib); \
- setNeededLibs(lib, 5, \
- "libX11.so.6", \
- "libxcb.so.1", \
- "libXau.so.6", \
- "libdl.so.2", \
- "libXdmcp.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 5, \
+ "libX11.so", \
+ "libxcb.so", \
+ "libXau.so", \
+ "libdl.so", \
+ "libXdmcp.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 5, \
+ "libX11.so.6", \
+ "libxcb.so.1", \
+ "libXau.so.6", \
+ "libdl.so.2", \
+ "libXdmcp.so.6");
+#endif
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedlibxfixes.c b/src/wrapped/wrappedlibxfixes.c
index 6ee42f8..90dbecc 100644
--- a/src/wrapped/wrappedlibxfixes.c
+++ b/src/wrapped/wrappedlibxfixes.c
@@ -11,15 +11,29 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxfixesName = "libXfixes.so.3";
+#ifdef ANDROID
+ const char* libxfixesName = "libXfixes.so";
+#else
+ const char* libxfixesName = "libXfixes.so.3";
+#endif
+
#define LIBNAME libxfixes
-#define CUSTOM_INIT \
- setNeededLibs(lib, 4, \
- "libX11.so.6", \
- "libxcb.so.1", \
- "libXau.so.6", \
- "libXdmcp.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so", \
+ "libxcb.so", \
+ "libXau.so", \
+ "libXdmcp.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so.6", \
+ "libxcb.so.1", \
+ "libXau.so.6", \
+ "libXdmcp.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxft.c b/src/wrapped/wrappedlibxft.c
index b779f93..175b987 100644
--- a/src/wrapped/wrappedlibxft.c
+++ b/src/wrapped/wrappedlibxft.c
@@ -11,15 +11,29 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxftName = "libXft.so.2";
+#ifdef ANDROID
+ const char* libxftName = "libXft.so";
+#else
+ const char* libxftName = "libXft.so.2";
+#endif
+
#define LIBNAME libxft
-#define CUSTOM_INIT \
- setNeededLibs(lib, 4, \
- "libX11.so.6", \
- "libfontconfig.so.1", \
- "libXrender.so.1", \
- "libfreetype.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so", \
+ "libfontconfig.so", \
+ "libXrender.so", \
+ "libfreetype.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so.6", \
+ "libfontconfig.so.1", \
+ "libXrender.so.1", \
+ "libfreetype.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxi.c b/src/wrapped/wrappedlibxi.c
index 0d2d065..d2d69be 100644
--- a/src/wrapped/wrappedlibxi.c
+++ b/src/wrapped/wrappedlibxi.c
@@ -11,11 +11,21 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxiName = "libXi.so.6";
+#ifdef ANDROID
+ const char* libxiName = "libXi.so";
+#else
+ const char* libxiName = "libXi.so.6";
+#endif
+
#define LIBNAME libxi
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxmu.c b/src/wrapped/wrappedlibxmu.c
index 225f682..16617cb 100644
--- a/src/wrapped/wrappedlibxmu.c
+++ b/src/wrapped/wrappedlibxmu.c
@@ -11,11 +11,21 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxmuName = "libXmu.so.6";
+#ifdef ANDROID
+ const char* libxmuName = "libXmu.so";
+#else
+ const char* libxmuName = "libXmu.so.6";
+#endif
+
#define LIBNAME libxmu
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxpm.c b/src/wrapped/wrappedlibxpm.c
index b978082..c4abc7f 100644
--- a/src/wrapped/wrappedlibxpm.c
+++ b/src/wrapped/wrappedlibxpm.c
@@ -11,10 +11,20 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxpmName = "libXpm.so.4";
+#ifdef ANDROID
+ const char* libxpmName = "libXpm.so";
+#else
+ const char* libxpmName = "libXpm.so.4";
+#endif
+
#define LIBNAME libxpm
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h" \ No newline at end of file
diff --git a/src/wrapped/wrappedlibxpresent.c b/src/wrapped/wrappedlibxpresent.c
index c5d13fd..2a5ec87 100644
--- a/src/wrapped/wrappedlibxpresent.c
+++ b/src/wrapped/wrappedlibxpresent.c
@@ -12,7 +12,12 @@
#include "x64emu.h"
#include "debug.h"
-const char* libxpresentName = "libXpresent.so.1";
+#ifdef ANDROID
+ const char* libxpresentName = "libXpresent.so";
+#else
+ const char* libxpresentName = "libXpresent.so.1";
+#endif
+
#define LIBNAME libxpresent
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxrandr.c b/src/wrapped/wrappedlibxrandr.c
index b74cca0..9303775 100644
--- a/src/wrapped/wrappedlibxrandr.c
+++ b/src/wrapped/wrappedlibxrandr.c
@@ -17,13 +17,26 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxrandrName = "libXrandr.so.2";
+#ifdef ANDROID
+ const char* libxrandrName = "libXrandr.so";
+#else
+ const char* libxrandrName = "libXrandr.so.2";
+#endif
+
#define LIBNAME libxrandr
-#define CUSTOM_INIT \
- setNeededLibs(lib, 3, \
- "libX11.so.6", \
- "libXext.so.6", \
- "libXrender.so.1");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 3, \
+ "libX11.so", \
+ "libXext.so", \
+ "libXrender.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 3, \
+ "libX11.so.6", \
+ "libXext.so.6", \
+ "libXrender.so.1");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxrender.c b/src/wrapped/wrappedlibxrender.c
index ff2c218..73fd266 100644
--- a/src/wrapped/wrappedlibxrender.c
+++ b/src/wrapped/wrappedlibxrender.c
@@ -11,15 +11,29 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxrenderName = "libXrender.so.1";
+#ifdef ANDROID
+ const char* libxrenderName = "libXrender.so";
+#else
+ const char* libxrenderName = "libXrender.so.1";
+#endif
+
#define LIBNAME libxrender
-#define CUSTOM_INIT \
- setNeededLibs(lib, 4, \
- "libX11.so.6", \
- "libxcb.so.1", \
- "libXau.so.6", \
- "libXdmcp.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so", \
+ "libxcb.so", \
+ "libXau.so", \
+ "libXdmcp.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 4, \
+ "libX11.so.6", \
+ "libxcb.so.1", \
+ "libXau.so.6", \
+ "libXdmcp.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxss.c b/src/wrapped/wrappedlibxss.c
index 00c00b9..34c1682 100644
--- a/src/wrapped/wrappedlibxss.c
+++ b/src/wrapped/wrappedlibxss.c
@@ -11,10 +11,20 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* libxssName = "libXss.so.1";
+#ifdef ANDROID
+ const char* libxssName = "libXss.so";
+#else
+ const char* libxssName = "libXss.so.1";
+#endif
+
#define LIBNAME libxss
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibxt.c b/src/wrapped/wrappedlibxt.c
index 6a7180f..f221f2a 100644
--- a/src/wrapped/wrappedlibxt.c
+++ b/src/wrapped/wrappedlibxt.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxtName = "libXt.so.6";
+#ifdef ANDROID
+ const char* libxtName = "libXt.so";
+#else
+ const char* libxtName = "libXt.so.6";
+#endif
+
#define LIBNAME libxt
#include "generated/wrappedlibxttypes.h"
@@ -122,9 +127,15 @@ EXPORT long my_XtAppAddInput(x64emu_t* emu, void* context, int source, void* con
return my->XtAppAddInput(context, source, cond, findInputCallbackFct(proc), data);
}
-#define CUSTOM_INIT \
- getMy(lib); \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedlibxtst.c b/src/wrapped/wrappedlibxtst.c
index 4ae3a68..4977f93 100644
--- a/src/wrapped/wrappedlibxtst.c
+++ b/src/wrapped/wrappedlibxtst.c
@@ -17,7 +17,12 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxtstName = "libXtst.so.6";
+#ifdef ANDROID
+ const char* libxtstName = "libXtst.so";
+#else
+ const char* libxtstName = "libXtst.so.6";
+#endif
+
#define LIBNAME libxtst
#include "generated/wrappedlibxtsttypes.h"
@@ -66,9 +71,15 @@ EXPORT int my_XRecordEnableContext(x64emu_t* emu, void* display, void* context,
return my->XRecordEnableContext(display, context, find_XRecordInterceptProc_Fct(cb), closure);
}
-#define CUSTOM_INIT \
- getMy(lib); \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ getMy(lib); \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#define CUSTOM_FINI \
freeMy();
diff --git a/src/wrapped/wrappedlibxxf86vm.c b/src/wrapped/wrappedlibxxf86vm.c
index 3f24e95..d6e7371 100644
--- a/src/wrapped/wrappedlibxxf86vm.c
+++ b/src/wrapped/wrappedlibxxf86vm.c
@@ -17,11 +17,20 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* libxxf86vmName = "libXxf86vm.so.1";
-#define LIBNAME libxxf86vm
+#ifdef ANDROID
+ const char* libxxf86vmName = "libXxf86vm.so";
+#else
+ const char* libxxf86vmName = "libXxf86vm.so.1";
+#endif
+#define LIBNAME libxxf86vm
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibz.c b/src/wrapped/wrappedlibz.c
index 4613c47..39468d4 100644
--- a/src/wrapped/wrappedlibz.c
+++ b/src/wrapped/wrappedlibz.c
@@ -15,7 +15,12 @@
#include "emu/x64emu_private.h"
#include "box64context.h"
-const char* libzName = "libz.so.1";
+#ifdef ANDROID
+ const char* libzName = "libz.so";
+#else
+ const char* libzName = "libz.so.1";
+#endif
+
#define LIBNAME libz
#include "generated/wrappedlibztypes.h"
diff --git a/src/wrapped/wrappedmpg123.c b/src/wrapped/wrappedmpg123.c
index 5b95749..dc538ab 100644
--- a/src/wrapped/wrappedmpg123.c
+++ b/src/wrapped/wrappedmpg123.c
@@ -17,7 +17,13 @@
#include "box64context.h"
#include "emu/x64emu_private.h"
-const char* mpg123Name = "libmpg123.so.0";
+const char* mpg123Name =
+#ifdef ANDROID
+ "libmpg123.so"
+#else
+ "libmpg123.so.0"
+#endif
+ ;
#define LIBNAME mpg123
#define ADDED_FUNCTIONS() \
diff --git a/src/wrapped/wrappedopenal.c b/src/wrapped/wrappedopenal.c
index 01b8c8e..1d063f8 100644
--- a/src/wrapped/wrappedopenal.c
+++ b/src/wrapped/wrappedopenal.c
@@ -52,7 +52,7 @@ static void* find_Request_Fct(void* fct)
#define GO(A) if(my_Request_fct_##A == 0) {my_Request_fct_##A = (uintptr_t)fct; return my_Request_##A; }
SUPER()
#undef GO
- printf_log(LOG_NONE, "Warning, no more slot for zlib Request callback\n");
+ printf_log(LOG_NONE, "Warning, no more slot for openal Request callback\n");
return NULL;
}
@@ -83,13 +83,15 @@ void fillALProcWrapper()
cnt = sizeof(openalsymbolmap)/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, openalsymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = openalsymbolmap[i].w;
+ kh_value(symbolmap, k).w = openalsymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
// and the my_ symbols map
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, openalmysymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = openalmysymbolmap[i].w;
+ kh_value(symbolmap, k).w = openalmysymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
my_context->alwrappers = symbolmap;
// fill my_* map
@@ -97,7 +99,8 @@ void fillALProcWrapper()
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, openalmysymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = openalmysymbolmap[i].w;
+ kh_value(symbolmap, k).w = openalmysymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
my_context->almymap = symbolmap;
}
@@ -134,19 +137,19 @@ EXPORT void* my_alGetProcAddress(x64emu_t* emu, void* name)
symbol = my->alGetProcAddress(name);
if(!symbol)
return NULL; // easy
- // check if alread bridged
- uintptr_t ret = CheckBridged(emu->context->system, symbol);
- if(ret)
- return (void*)ret; // already bridged
// get wrapper
k = kh_get(symbolmap, emu->context->alwrappers, rname);
if(k==kh_end(emu->context->alwrappers)) {
printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname);
return NULL;
}
- const char* constname = kh_key(emu->context->alwrappers, k);
- AddOffsetSymbol(emu->context->maplib, symbol, rname);
- return (void*)AddBridge(emu->context->system, kh_value(emu->context->alwrappers, k), symbol, 0, constname);
+ symbol1_t *s = &kh_value(emu->context->alwrappers, k);
+ if(!s->resolved) {
+ const char* constname = kh_key(emu->context->alwrappers, k);
+ s->addr = AddBridge(emu->context->system, s->w, symbol, 0, constname);
+ s->resolved = 1;
+ }
+ return (void*)s->addr;
}
EXPORT void* my_alcGetProcAddress(x64emu_t* emu, void* device, void* name)
@@ -170,18 +173,19 @@ EXPORT void* my_alcGetProcAddress(x64emu_t* emu, void* device, void* name)
symbol = my->alcGetProcAddress(device, name);
if(!symbol)
return NULL; // easy
- uintptr_t ret = CheckBridged(emu->context->system, symbol);
- if(ret)
- return (void*)ret; // already bridged
// get wrapper
k = kh_get(symbolmap, emu->context->alwrappers, rname);
if(k==kh_end(emu->context->alwrappers)) {
printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname);
return NULL;
}
- const char* constname = kh_key(emu->context->alwrappers, k);
- AddOffsetSymbol(emu->context->maplib, symbol, rname);
- return (void*)AddBridge(emu->context->system, kh_value(emu->context->alwrappers, k), symbol, 0, constname);
+ symbol1_t *s = &kh_value(emu->context->alwrappers, k);
+ if(!s->resolved) {
+ const char* constname = kh_key(emu->context->alwrappers, k);
+ s->addr = AddBridge(emu->context->system, s->w, symbol, 0, constname);
+ s->resolved = 1;
+ }
+ return (void*)s->addr;
}
EXPORT void my_alRequestFoldbackStart(x64emu_t *emu, int32_t mode, int32_t count, int32_t length, void* mem, void* cb)
diff --git a/src/wrapped/wrappedopencl.c b/src/wrapped/wrappedopencl.c
new file mode 100644
index 0000000..067482e
--- /dev/null
+++ b/src/wrapped/wrappedopencl.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "box64context.h"
+#include "librarian.h"
+#include "myalign.h"
+
+const char* openclName = "libOpenCL.so.1";
+#define LIBNAME opencl
+
+#include "generated/wrappedopencltypes.h"
+
+#include "wrappercallback.h"
+
+#define SUPER() \
+GO(0) \
+GO(1) \
+GO(2) \
+GO(3) \
+GO(4)
+
+// notify_program ...
+#define GO(A) \
+static uintptr_t my_notify_program_fct_##A = 0; \
+static void my_notify_program_##A(void* a, void* b) \
+{ \
+ RunFunctionFmt(my_notify_program_fct_##A, "pp", a, b); \
+}
+SUPER()
+#undef GO
+static void* find_notify_program_Fct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_notify_program_fct_##A == (uintptr_t)fct) return my_notify_program_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_notify_program_fct_##A == 0) {my_notify_program_fct_##A = (uintptr_t)fct; return my_notify_program_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for opencl notify_program callback\n");
+ return NULL;
+}
+// notity_context ...
+#define GO(A) \
+static uintptr_t my_notity_context_fct_##A = 0; \
+static void my_notity_context_##A(void* a, void* b, size_t c, void* d) \
+{ \
+ RunFunctionFmt(my_notity_context_fct_##A, "ppLp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* find_notity_context_Fct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_notity_context_fct_##A == (uintptr_t)fct) return my_notity_context_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_notity_context_fct_##A == 0) {my_notity_context_fct_##A = (uintptr_t)fct; return my_notity_context_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for opencl notity_context callback\n");
+ return NULL;
+}
+
+#undef SUPER
+
+EXPORT int my_clBuildProgram(x64emu_t* emu, void* program, uint32_t num, void* devices, void* options, void* f, void* data)
+{
+ return my->clBuildProgram(program, num, devices, options, find_notify_program_Fct(f), data);
+}
+
+EXPORT void* my_clCreateContext(x64emu_t* emu, void* prop, uint32_t num, void* devices, void* f, void* data, void* ret)
+{
+ return my->clCreateContext(prop, num, devices, find_notity_context_Fct(f), data, ret);
+}
+
+EXPORT void* my_clCreateContextFromType(x64emu_t* emu, void* prop, uint32_t type, void* f, void* data, void* ret)
+{
+ return my->clCreateContextFromType(prop, type, find_notity_context_Fct(f), data, ret);
+}
+
+#define CUSTOM_INIT \
+ getMy(lib);
+
+#define CUSTOM_FINI \
+ freeMy();
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedopencl_private.h b/src/wrapped/wrappedopencl_private.h
new file mode 100644
index 0000000..c4c818f
--- /dev/null
+++ b/src/wrapped/wrappedopencl_private.h
@@ -0,0 +1,135 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error Meh...
+#endif
+
+GOM(clBuildProgram, iFEpupppp)
+//GO(clCloneKernel,
+//GO(clCompileProgram,
+GO(clCreateBuffer, pFpuLpp)
+//GO(clCreateBufferWithProperties,
+GO(clCreateCommandQueue, pFppup)
+//GO(clCreateCommandQueueWithProperties,
+GOM(clCreateContext, pFEpupppp)
+GOM(clCreateContextFromType, pFEpuppp)
+//GO(clCreateFromGLBuffer,
+//GO(clCreateFromGLRenderbuffer,
+//GO(clCreateFromGLTexture,
+//GO(clCreateFromGLTexture2D,
+//GO(clCreateFromGLTexture3D,
+GO(clCreateImage, pFpupppp)
+GO(clCreateImage2D, pFpupLLLpp)
+GO(clCreateImage3D, pFpupLLLLLpp)
+//GO(clCreateImageWithProperties,
+GO(clCreateKernel, pFppp)
+GO(clCreateKernelsInProgram, iFpupp)
+//GO(clCreatePipe,
+GO(clCreateProgramWithBinary, pFpuppppp)
+GO(clCreateProgramWithBuiltInKernels, pFpuppp)
+//GO(clCreateProgramWithIL,
+GO(clCreateProgramWithSource, pFpuppp)
+GO(clCreateSampler, pFpuuup)
+//GO(clCreateSamplerWithProperties,
+GO(clCreateSubBuffer, pFpuupp)
+GO(clCreateSubDevices, iFppupp)
+GO(clCreateUserEvent, pFpp)
+//GO(clEnqueueAcquireGLObjects,
+GO(clEnqueueBarrier, iFp)
+GO(clEnqueueBarrierWithWaitList, iFpupp)
+GO(clEnqueueCopyBuffer, iFpppLLLupp)
+GO(clEnqueueCopyBufferRect, iFppppppLLLLupp)
+GO(clEnqueueCopyBufferToImage, iFpppLppupp)
+GO(clEnqueueCopyImage, iFppppppupp)
+GO(clEnqueueCopyImageToBuffer, iFpppppLupp)
+GO(clEnqueueFillBuffer, iFpppLLLupp)
+GO(clEnqueueFillImage, iFpppppupp)
+GO(clEnqueueMapBuffer, pFppuuLLuppp)
+GO(clEnqueueMapImage, pFppuuppppuppp)
+GO(clEnqueueMarker, iFpp)
+GO(clEnqueueMarkerWithWaitList, iFpupp)
+GO(clEnqueueMigrateMemObjects, iFpupuupp)
+//GO(clEnqueueNativeKernel,
+GO(clEnqueueNDRangeKernel, iFppupppupp)
+GO(clEnqueueReadBuffer, iFppuLLpupp)
+GO(clEnqueueReadBufferRect, iFppupppLLLLpupp)
+GO(clEnqueueReadImage, iFppuppLLpupp)
+//GO(clEnqueueReleaseGLObjects,
+//GO(clEnqueueSVMFree,
+//GO(clEnqueueSVMMap,
+//GO(clEnqueueSVMMemcpy,
+//GO(clEnqueueSVMMemFill,
+//GO(clEnqueueSVMMigrateMem,
+//GO(clEnqueueSVMUnmap,
+GO(clEnqueueTask, iFppupp)
+GO(clEnqueueUnmapMemObject, iFpppupp)
+GO(clEnqueueWaitForEvents, iFpup)
+GO(clEnqueueWriteBuffer, iFppuLLpupp)
+GO(clEnqueueWriteBufferRect, iFppupppLLLLpupp)
+GO(clEnqueueWriteImage, iFppuppLLpupp)
+GO(clFinish, iFp)
+GO(clFlush, iFp)
+GO(clGetCommandQueueInfo, iFpuLpp)
+GO(clGetContextInfo, iFpuLpp)
+//GO(clGetDeviceAndHostTimer,
+GO(clGetDeviceIDs, iFpuupp)
+GO(clGetDeviceInfo, iFpuLpL)
+GO(clGetEventInfo, iFpuLpp)
+GO(clGetEventProfilingInfo, iFpuLpp)
+//GO(clGetExtensionFunctionAddress,
+//GO(clGetExtensionFunctionAddressForPlatform,
+//GO(clGetGLObjectInfo,
+//GO(clGetGLTextureInfo,
+//GO(clGetHostTimer,
+GO(clGetImageInfo, pFpuLpp)
+GO(clGetKernelArgInfo, iFpuuLpp)
+GO(clGetKernelInfo, iFpuLpp)
+//GO(clGetKernelSubGroupInfo,
+GO(clGetKernelWorkGroupInfo, iFppuLpp)
+GO(clGetMemObjectInfo, iFpuLpp)
+//GO(clGetPipeInfo,
+GO(clGetPlatformIDs, iFupp)
+GO(clGetPlatformInfo, iFpuLpp)
+GO(clGetProgramBuildInfo, iFppuLpp)
+GO(clGetProgramInfo, iFpuLpL)
+GO(clGetSamplerInfo, iFpuLpp)
+GO(clGetSupportedImageFormats, iFpuuupp)
+//GO(clLinkProgram,
+GO(clReleaseCommandQueue, iFp)
+GO(clReleaseContext, iFp)
+GO(clReleaseDevice, iFp)
+GO(clReleaseEvent, iFp)
+GO(clReleaseKernel, iFp)
+GO(clReleaseMemObject, iFp)
+GO(clReleaseProgram, iFp)
+GO(clReleaseSampler, iFp)
+GO(clRetainCommandQueue, iFp)
+GO(clRetainContext, iFp)
+GO(clRetainDevice, iFp)
+GO(clRetainEvent, iFp)
+GO(clRetainKernel, iFp)
+GO(clRetainMemObject, iFp)
+GO(clRetainProgram, iFp)
+GO(clRetainSampler, iFp)
+//GO(clSetCommandQueueProperty,
+//GO(clSetContextDestructorCallback,
+//GO(clSetDefaultDeviceCommandQueue,
+//GO(clSetEventCallback,
+GO(clSetKernelArg, iFpuLp)
+//GO(clSetKernelArgSVMPointer,
+//GO(clSetKernelExecInfo,
+//GO(clSetMemObjectDestructorCallback,
+//GO(clSetProgramReleaseCallback,
+//GO(clSetProgramSpecializationConstant,
+GO(clSetUserEventStatus, iFpi)
+//GO(clSVMAlloc,
+//GO(clSVMFree,
+GO(clUnloadCompiler, iFv)
+GO(clUnloadPlatformCompiler, iFp)
+GO(clWaitForEvents, iFup)
+
+//OPENCL_1.0
+//OPENCL_1.1
+//OPENCL_1.2
+//OPENCL_2.0
+//OPENCL_2.1
+//OPENCL_2.2
+//OPENCL_3.0
diff --git a/src/wrapped/wrappedpng16.c b/src/wrapped/wrappedpng16.c
index 290162b..ba00808 100644
--- a/src/wrapped/wrappedpng16.c
+++ b/src/wrapped/wrappedpng16.c
@@ -39,9 +39,9 @@ GO(3)
// user_write
#define GO(A) \
static uintptr_t my_user_write_fct_##A = 0; \
-static void my_user_write_##A(void* png_ptr, void* data, int32_t length) \
+static void my_user_write_##A(void* png_ptr, void* data, size_t length) \
{ \
- RunFunctionFmt(my_user_write_fct_##A, "ppi", png_ptr, data, length);\
+ RunFunctionFmt(my_user_write_fct_##A, "ppL", png_ptr, data, length);\
}
SUPER()
#undef GO
@@ -83,9 +83,9 @@ static void* finduser_flushFct(void* fct)
// user_read
#define GO(A) \
static uintptr_t my_user_read_fct_##A = 0; \
-static void my_user_read_##A(void* png_ptr, void* data, int32_t length) \
+static void my_user_read_##A(void* png_ptr, void* data, size_t length) \
{ \
- RunFunctionFmt(my_user_read_fct_##A, "ppi", png_ptr, data, length);\
+ RunFunctionFmt(my_user_read_fct_##A, "ppL", png_ptr, data, length);\
}
SUPER()
#undef GO
diff --git a/src/wrapped/wrappedpulse.c b/src/wrapped/wrappedpulse.c
index f5ec5d4..7d782f2 100644
--- a/src/wrapped/wrappedpulse.c
+++ b/src/wrapped/wrappedpulse.c
@@ -17,7 +17,12 @@
#include "librarian.h"
#include "myalign.h"
-const char* pulseName = "libpulse.so.0";
+#ifdef ANDROID
+ const char* pulseName = "libpulse.so";
+#else
+ const char* pulseName = "libpulse.so.0";
+#endif
+
#define LIBNAME pulse
// TODO: check my_pa_proplist_setf (not using generated/...)
@@ -61,11 +66,7 @@ typedef void (*vFipippV_t)(int, void*, int, void*, void*, void*);
// TODO: change that static for a map ptr2ptr?
static my_pa_mainloop_api_t my_mainloop_api = {0};
-static my_pa_mainloop_api_t my_mainloop_native = {0};
-static int mainloop_inited = 0;
-static my_pa_mainloop_api_t* my_mainloop_ref = NULL;
-static my_pa_mainloop_api_t* my_mainloop_orig = NULL;
-
+static void UpdateautobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api);
// utility functions
#define SUPER() \
@@ -131,12 +132,12 @@ static void* findFreeAPIFct(void* fct)
return NULL;
}
-#define GO(A) \
-static uintptr_t my_io_event_fct_##A = 0; \
+#define GO(A) \
+static uintptr_t my_io_event_fct_##A = 0; \
static void my_io_event_##A(my_pa_mainloop_api_t* api, void* e, int fd, int events, void* data) \
-{ \
- if(api==my_mainloop_orig) api=my_mainloop_ref; \
- RunFunctionFmt(my_io_event_fct_##A, "ppiip", api, e, fd, events, data); \
+{ \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_io_event_fct_##A, "ppiip", api, e, fd, events, data); \
}
SUPER()
#undef GO
@@ -154,12 +155,12 @@ static void* findIOEventFct(void* fct)
return NULL;
}
-#define GO(A) \
-static uintptr_t my_time_event_fct_##A = 0; \
+#define GO(A) \
+static uintptr_t my_time_event_fct_##A = 0; \
static void my_time_event_##A(my_pa_mainloop_api_t* api, void* e, void* tv, void* data) \
-{ \
- if(api==my_mainloop_orig) api=my_mainloop_ref; \
- RunFunctionFmt(my_time_event_fct_##A, "pppp", api, e, tv, data); \
+{ \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_time_event_fct_##A, "pppp", api, e, tv, data); \
}
SUPER()
#undef GO
@@ -178,12 +179,12 @@ static void* findTimeEventFct(void* fct)
return NULL;
}
-#define GO(A) \
-static uintptr_t my_defer_event_fct_##A = 0; \
-static void my_defer_event_##A(my_pa_mainloop_api_t* api, void* e, void* data) \
-{ \
- if(api==my_mainloop_orig) api=my_mainloop_ref; \
- RunFunctionFmt(my_defer_event_fct_##A, "ppp", api, e, data); \
+#define GO(A) \
+static uintptr_t my_defer_event_fct_##A = 0; \
+static void my_defer_event_##A(my_pa_mainloop_api_t* api, void* e, void* data) \
+{ \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_defer_event_fct_##A, "ppp", api, e, data); \
}
SUPER()
#undef GO
@@ -228,8 +229,8 @@ static void* find_poll_Fct(void* fct)
static uintptr_t my_signal_fct_##A = 0; \
static void my_signal_##A(my_pa_mainloop_api_t* api, void* e, int sig, void *data) \
{ \
- if(api==my_mainloop_orig) api=my_mainloop_ref; \
- RunFunctionFmt(my_signal_fct_##A, "ppip", api, e, sig, data); \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_signal_fct_##A, "ppip", api, e, sig, data); \
}
SUPER()
#undef GO
@@ -251,8 +252,8 @@ static void* find_signal_Fct(void* fct)
static uintptr_t my_signal_destroy_fct_##A = 0; \
static void my_signal_destroy_##A(my_pa_mainloop_api_t* api, void* e, void *data) \
{ \
- if(api==my_mainloop_orig) api=my_mainloop_ref; \
- RunFunctionFmt(my_signal_destroy_fct_##A, "ppp", api, e, data); \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_signal_destroy_fct_##A, "ppp", api, e, data); \
}
SUPER()
#undef GO
@@ -691,11 +692,11 @@ static void* find_card_info_Fct(void* fct)
return NULL;
}
// source_output_info
-#define GO(A) \
+#define GO(A) \
static uintptr_t my_source_output_info_fct_##A = 0; \
static void my_source_output_info_##A(void* a, void* b, int c, void* d) \
-{ \
- RunFunctionFmt(my_source_output_info_fct_##A, "ppip", a, b, c, d); \
+{ \
+ RunFunctionFmt(my_source_output_info_fct_##A, "ppip", a, b, c, d); \
}
SUPER()
#undef GO
@@ -717,7 +718,7 @@ static void* find_source_output_info_Fct(void* fct)
static uintptr_t my_device_restore_subscribe_fct_##A = 0; \
static void my_device_restore_subscribe_##A(void* a, int b, uint32_t c, void* d) \
{ \
- RunFunctionFmt(my_device_restore_subscribe_fct_##A, "piup", a, b, c, d); \
+ RunFunctionFmt(my_device_restore_subscribe_fct_##A, "piup", a, b, c, d); \
}
SUPER()
#undef GO
@@ -734,267 +735,348 @@ static void* find_device_restore_subscribe_Fct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for pulse audio device_restore_subscribe callback\n");
return NULL;
}
-
-#undef SUPER
-
-
-// Mainloop functions
-// but first, all cb from the pa_mainloop_api (serioulsy, how many callback and callback inside callback there is in pulse audio?!!!)
-
-// Native version of the mailoop_api. Called from x64 space
-
-static void* native_io_new(void* api, int fd, int events, void* cb, void *data)
-{
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- // need to wrap the callback!
- void* c = findIOEventFct(cb);
- return ((pFpiipp_t)my_mainloop_native.io_new)(api, fd, events, c, data);
+// mainloop_once
+#define GO(A) \
+static uintptr_t my_mainloop_once_fct_##A = 0; \
+static void my_mainloop_once_##A(void* api, void* b) \
+{ \
+ UpdateautobridgeMainloopAPI(thread_get_emu(), my_lib->w.bridge, api); \
+ RunFunctionFmt(my_mainloop_once_fct_##A, "pp", api, b); \
}
-static void native_io_enable(void* e, int events)
+SUPER()
+#undef GO
+static void* find_mainloop_once_Fct(void* fct)
{
- return ((vFpi_t)my_mainloop_native.io_enable)(e, events);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_mainloop_once_fct_##A == (uintptr_t)fct) return my_mainloop_once_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_mainloop_once_fct_##A == 0) {my_mainloop_once_fct_##A = (uintptr_t)fct; return my_mainloop_once_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio mainloop_once callback\n");
+ return NULL;
}
-static void native_io_free(void* e)
-{
- return ((vFp_t)my_mainloop_native.io_free)(e);
+// io_new
+#define GO(A) \
+static uintptr_t my_io_new_fct_##A = 0; \
+static void* my_io_new_##A(void* api, int fd, int events, void* cb, void* data) \
+{ \
+ return (void*)RunFunctionFmt(my_io_new_fct_##A, "piipp", api, fd, events, AddCheckBridge(my_lib->w.bridge, vFppiip, cb, 0, "my_io_new_cb"),data); \
}
-static void native_io_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_io_new_Fct(void* fct)
{
- // need to wrap the callback!
- void* c = findFreeAPIFct(cb);
- return ((vFpp_t)my_mainloop_native.io_set_destroy)(e, c);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_io_new_fct_##A == (uintptr_t)fct) return my_io_new_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_io_new_fct_##A == 0) {my_io_new_fct_##A = (uintptr_t)fct; return my_io_new_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_new callback\n");
+ return NULL;
}
-
-static void* native_time_new(void* api, void* tv, void* cb, void* data)
-{
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- // need to wrap the callback!
- void* c = findTimeEventFct(cb);
- return ((pFpppp_t)my_mainloop_native.time_new)(api, tv, c, data);
+// io_enable
+#define GO(A) \
+static uintptr_t my_io_enable_fct_##A = 0; \
+static void* my_io_enable_##A(void* api, int events) \
+{ \
+ RunFunctionFmt(my_io_enable_fct_##A, "pi", api, events); \
}
-static void native_time_restart(void* e, void* tv)
+SUPER()
+#undef GO
+static void* find_io_enable_Fct(void* fct)
{
- return ((vFpp_t)my_mainloop_native.time_restart)(e, tv);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_io_enable_fct_##A == (uintptr_t)fct) return my_io_enable_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_io_enable_fct_##A == 0) {my_io_enable_fct_##A = (uintptr_t)fct; return my_io_enable_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_enable callback\n");
+ return NULL;
}
-static void native_time_free(void* e)
-{
- return ((vFp_t)my_mainloop_native.time_free)(e);
+// io_free
+#define GO(A) \
+static uintptr_t my_io_free_fct_##A = 0; \
+static void* my_io_free_##A(void* e) \
+{ \
+ RunFunctionFmt(my_io_free_fct_##A, "p", e); \
}
-static void native_time_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_io_free_Fct(void* fct)
{
- // need to wrap the callback!
- void* c = findFreeAPIFct(cb);
- return ((vFpp_t)my_mainloop_native.time_set_destroy)(e, c);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_io_free_fct_##A == (uintptr_t)fct) return my_io_free_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_io_free_fct_##A == 0) {my_io_free_fct_##A = (uintptr_t)fct; return my_io_free_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_free callback\n");
+ return NULL;
}
-
-static void* native_defer_new(void* api, void* cb, void* data)
-{
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- // need to wrap the callback!
- void* c = findDeferEventFct(cb);
- return ((pFppp_t)my_mainloop_native.defer_new)(api, c, data);
+// io_set_destroy
+#define GO(A) \
+static uintptr_t my_io_set_destroy_fct_##A = 0; \
+static void my_io_set_destroy_##A(void* e, void* cb) \
+{ \
+ RunFunctionFmt(my_io_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_io_set_destroy_cb")); \
}
-static void native_defer_enable(void* e, int b)
+SUPER()
+#undef GO
+static void* find_io_set_destroy_Fct(void* fct)
{
- return ((vFpi_t)my_mainloop_native.defer_enable)(e, b);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_io_set_destroy_fct_##A == (uintptr_t)fct) return my_io_set_destroy_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_io_set_destroy_fct_##A == 0) {my_io_set_destroy_fct_##A = (uintptr_t)fct; return my_io_set_destroy_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio io_set_destroy callback\n");
+ return NULL;
}
-static void native_defer_free(void* e)
-{
- return ((vFp_t)my_mainloop_native.defer_free)(e);
+// time_new
+#define GO(A) \
+static uintptr_t my_time_new_fct_##A = 0; \
+static void* my_time_new_##A(void* api, void* t, void* cb, void* data) \
+{ \
+ return (void*)RunFunctionFmt(my_time_new_fct_##A, "pppp", api, t, AddCheckBridge(my_lib->w.bridge, vFpppp, cb, 0, "my_time_new_cb"), data); \
}
-static void native_defer_set_destroy(void* e, void* cb)
+SUPER()
+#undef GO
+static void* find_time_new_Fct(void* fct)
{
- // need to wrap the callback!
- void* c = findFreeAPIFct(cb);
- return ((vFpp_t)my_mainloop_native.defer_set_destroy)(e, c);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_time_new_fct_##A == (uintptr_t)fct) return my_time_new_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_time_new_fct_##A == 0) {my_time_new_fct_##A = (uintptr_t)fct; return my_time_new_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_new callback\n");
+ return NULL;
}
-
-static void native_quit(void* api, int retval)
-{
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- return ((vFpi_t)my_mainloop_native.quit)(api, retval);
+// time_restart
+#define GO(A) \
+static uintptr_t my_time_restart_fct_##A = 0; \
+static void* my_time_restart_##A(void* e, void* t) \
+{ \
+ RunFunctionFmt(my_time_restart_fct_##A, "pp", e, t); \
}
-
-// Emulated version. Called from native space (meh, crossing stuff are hard to follow)
-static void* my_io_new(void* api, int fd, int events, void* cb, void *userdata)
+SUPER()
+#undef GO
+static void* find_time_restart_Fct(void* fct)
{
- uintptr_t b = (uintptr_t)cb;
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_new);
- if(fnc) {
- if(fnc==native_io_new) fnc=my_mainloop_native.io_new;
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- return ((pFpiipp_t)fnc)(api, fd, events, cb, userdata);
- }
-
- bridge_t* bridge = my_lib->w.bridge;
- if(cb)
- b = AddCheckBridge(bridge, vFppiip, cb, 0, NULL);
- if(api==my_mainloop_orig) api=my_mainloop_ref; // need emulated version
- return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->io_new, "piipp", api, fd, events, b, userdata);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_time_restart_fct_##A == (uintptr_t)fct) return my_time_restart_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_time_restart_fct_##A == 0) {my_time_restart_fct_##A = (uintptr_t)fct; return my_time_restart_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_restart callback\n");
+ return NULL;
}
-static void my_io_enable(void* e, int events)
-{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_enable);
- if(fnc==native_io_enable) fnc=my_mainloop_native.io_enable;
- if(fnc)
- return ((vFpi_t)fnc)(e, events);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->io_enable, "pi", e, events);
+// time_free
+#define GO(A) \
+static uintptr_t my_time_free_fct_##A = 0; \
+static void* my_time_free_##A(void* e) \
+{ \
+ RunFunctionFmt(my_time_free_fct_##A, "p", e); \
}
-static void my_io_free(void* e)
+SUPER()
+#undef GO
+static void* find_time_free_Fct(void* fct)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_free);
- if(fnc==native_io_free) fnc=my_mainloop_native.io_free;
- if(fnc)
- return ((vFp_t)fnc)(e);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->io_free, "p", e);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_time_free_fct_##A == (uintptr_t)fct) return my_time_free_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_time_free_fct_##A == 0) {my_time_free_fct_##A = (uintptr_t)fct; return my_time_free_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_free callback\n");
+ return NULL;
}
-static void my_io_set_destroy(void* e, void* cb)
-{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->io_set_destroy);
- if(fnc==native_io_set_destroy) fnc=my_mainloop_native.io_set_destroy;
- if(fnc)
- return ((vFpp_t)fnc)(e, cb);
-
- bridge_t* bridge = my_lib->w.bridge;
- uintptr_t b = 0;
- if(cb) {
- b = CheckBridged(bridge, cb);
- if(!b)
- b = AddBridge(bridge, vFppp, cb, 0, NULL);
- }
- RunFunctionFmt((uintptr_t)my_mainloop_ref->io_set_destroy, "pp", e, b);
+// time_set_destroy
+#define GO(A) \
+static uintptr_t my_time_set_destroy_fct_##A = 0; \
+static void my_time_set_destroy_##A(void* e, void* cb) \
+{ \
+ RunFunctionFmt(my_time_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_time_set_destroy_cb")); \
}
-
-static void* my_time_new(void* api, void* tv, void* cb, void* data)
+SUPER()
+#undef GO
+static void* find_time_set_destroy_Fct(void* fct)
{
- uintptr_t b = (uintptr_t)cb;
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_new);
- if(fnc) {
- if(fnc==native_time_new) fnc=my_mainloop_native.time_new;
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- return ((pFpppp_t)fnc)(api, tv, (void*)b, data);
- }
-
- // need to bridge the callback!
- bridge_t* bridge = my_lib->w.bridge;
- if(cb)
- b = AddCheckBridge(bridge, vFpppp, cb, 0, NULL);
- if(api==my_mainloop_orig) api=my_mainloop_ref; // need emulated version
- return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->time_new, "pppp", api, tv, b, data);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_time_set_destroy_fct_##A == (uintptr_t)fct) return my_time_set_destroy_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_time_set_destroy_fct_##A == 0) {my_time_set_destroy_fct_##A = (uintptr_t)fct; return my_time_set_destroy_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio time_set_destroy callback\n");
+ return NULL;
}
-static void my_time_restart(void* e, void* tv)
-{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_restart);
- if(fnc==native_time_restart) fnc=my_mainloop_native.time_restart;
- if(fnc)
- return ((vFpp_t)fnc)(e, tv);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->time_restart, "pp", e, tv);
+// defer_new
+#define GO(A) \
+static uintptr_t my_defer_new_fct_##A = 0; \
+static void* my_defer_new_##A(void* api, void* cb, void* data) \
+{ \
+ return (void*)RunFunctionFmt(my_defer_new_fct_##A, "ppp", api, AddCheckBridge(my_lib->w.bridge, vFpppp, cb, 0, "my_defer_new_cb"), data); \
}
-static void my_time_free(void* e)
+SUPER()
+#undef GO
+static void* find_defer_new_Fct(void* fct)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_free);
- if(fnc==native_time_free) fnc=my_mainloop_native.time_free;
- if(fnc)
- return ((vFp_t)fnc)(e);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->time_free, "p", e);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_defer_new_fct_##A == (uintptr_t)fct) return my_defer_new_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_defer_new_fct_##A == 0) {my_defer_new_fct_##A = (uintptr_t)fct; return my_defer_new_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_new callback\n");
+ return NULL;
}
-static void my_time_set_destroy(void* e, void* cb)
-{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->time_set_destroy);
- if(fnc==native_time_set_destroy) fnc=my_mainloop_native.time_set_destroy;
- if(fnc)
- return ((vFpp_t)fnc)(e, cb);
-
- bridge_t* bridge = my_lib->w.bridge;
- uintptr_t b = 0;
- if(cb)
- b = AddCheckBridge(bridge, vFppp, cb, 0, NULL);
- RunFunctionFmt((uintptr_t)my_mainloop_ref->time_set_destroy, "pp", e, b);
+// defer_enable
+#define GO(A) \
+static uintptr_t my_defer_enable_fct_##A = 0; \
+static void* my_defer_enable_##A(void* e, int b) \
+{ \
+ RunFunctionFmt(my_defer_enable_fct_##A, "pi", e, b); \
}
-
-static void* my_defer_new(void* api, void* cb, void* data)
+SUPER()
+#undef GO
+static void* find_defer_enable_Fct(void* fct)
{
- uintptr_t b = (uintptr_t)cb;
- static void* old_defer_new = NULL;
- static void* old_fnc = NULL;
- void* fnc = NULL;
- if(old_defer_new == my_mainloop_ref->defer_new)
- fnc = old_fnc;
- else {
- old_fnc = fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_new);
- old_defer_new = my_mainloop_ref->defer_new;
- }
- if(fnc) {
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- if(fnc==native_defer_new) fnc=my_mainloop_native.defer_new;
- return ((pFppp_t)fnc)(api, cb, data);
- }
-
- // need to bridge the callback!
- bridge_t* bridge = my_lib->w.bridge;
- if(cb) {
- b = CheckBridged(bridge, cb);
- if(!b)
- b = AddBridge(bridge, vFppp, cb, 0, NULL);
- }
- if(api==my_mainloop_orig) api=my_mainloop_ref; // need emulated version
- return (void*)RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_new, "ppp", api, b, data);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_defer_enable_fct_##A == (uintptr_t)fct) return my_defer_enable_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_defer_enable_fct_##A == 0) {my_defer_enable_fct_##A = (uintptr_t)fct; return my_defer_enable_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_enable callback\n");
+ return NULL;
}
-static void my_defer_enable(void* e, int b)
+// defer_free
+#define GO(A) \
+static uintptr_t my_defer_free_fct_##A = 0; \
+static void* my_defer_free_##A(void* e) \
+{ \
+ RunFunctionFmt(my_defer_free_fct_##A, "p", e); \
+}
+SUPER()
+#undef GO
+static void* find_defer_free_Fct(void* fct)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_enable);
- if(fnc==native_defer_enable) fnc=my_mainloop_native.defer_enable;
- if(fnc)
- return ((vFpi_t)fnc)(e, b);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_enable, "pi", e, b);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_defer_free_fct_##A == (uintptr_t)fct) return my_defer_free_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_defer_free_fct_##A == 0) {my_defer_free_fct_##A = (uintptr_t)fct; return my_defer_free_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_free callback\n");
+ return NULL;
+}
+// defer_set_destroy
+#define GO(A) \
+static uintptr_t my_defer_set_destroy_fct_##A = 0; \
+static void my_defer_set_destroy_##A(void* e, void* cb) \
+{ \
+ RunFunctionFmt(my_defer_set_destroy_fct_##A, "pp", e, AddCheckBridge(my_lib->w.bridge, vFppp, cb, 0, "my_defer_set_destroy_cb")); \
}
-static void my_defer_free(void* e)
+SUPER()
+#undef GO
+static void* find_defer_set_destroy_Fct(void* fct)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_free);
- if(fnc==native_defer_free) fnc=my_mainloop_native.defer_free;
- if(fnc)
- return ((vFp_t)fnc)(e);
-
- RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_free, "p", e);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_defer_set_destroy_fct_##A == (uintptr_t)fct) return my_defer_set_destroy_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_defer_set_destroy_fct_##A == 0) {my_defer_set_destroy_fct_##A = (uintptr_t)fct; return my_defer_set_destroy_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio defer_set_destroy callback\n");
+ return NULL;
}
-static void my_defer_set_destroy(void* e, void* cb)
+// quit
+#define GO(A) \
+static uintptr_t my_quit_fct_##A = 0; \
+static void* my_quit_##A(void* e, int retval) \
+{ \
+ RunFunctionFmt(my_quit_fct_##A, "pi", e, retval); \
+}
+SUPER()
+#undef GO
+static void* find_quit_Fct(void* fct)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->defer_set_destroy);
- if(fnc==native_defer_set_destroy) fnc=my_mainloop_native.defer_set_destroy;
- if(fnc)
- return ((vFpp_t)fnc)(e, cb);
-
- bridge_t* bridge = my_lib->w.bridge;
- uintptr_t b = 0;
- if(cb)
- b = AddCheckBridge(bridge, vFppp, cb, 0, NULL);
- RunFunctionFmt((uintptr_t)my_mainloop_ref->defer_set_destroy, "pp", e, b);
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_quit_fct_##A == (uintptr_t)fct) return my_quit_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_quit_fct_##A == 0) {my_quit_fct_##A = (uintptr_t)fct; return my_quit_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for pulse audio quit callback\n");
+ return NULL;
}
-static void my_quit(void* api, int retval)
+#undef SUPER
+
+static void UpdateautobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api)
{
- void* fnc = GetNativeFnc((uintptr_t)my_mainloop_ref->quit);
- if(fnc) {
- if(fnc==native_quit) fnc=my_mainloop_native.quit;
- if(api==my_mainloop_ref) api=my_mainloop_orig; // need native version
- return ((vFpi_t)fnc)(api, retval);
+ if(!api) {
+ return;
}
-
- if(api==my_mainloop_orig) api=my_mainloop_ref; // need emulated version
- RunFunctionFmt((uintptr_t)my_mainloop_ref->quit, "pi", api, retval);
+ #define GO(A, W) if(api->A!=my_mainloop_api.A) {api->A=find_##A##_Fct(api->A); AddAutomaticBridge(emu, bridge, W, api->A, 0, NULL);}
+ GO(io_new, pFpiipp);
+ GO(io_enable, vFpi);
+ GO(io_free, vFp);
+ GO(io_set_destroy, vFpp);
+ GO(time_new, pFpppp);
+ GO(time_restart, vFpp);
+ GO(time_free, vFp);
+ GO(time_set_destroy, vFpp);
+ GO(defer_new, pFppp);
+ GO(defer_enable, vFpi);
+ GO(defer_free, vFp);
+ GO(defer_set_destroy, vFpp);
+ GO(quit, vFpi);
+ #undef GO
+ memcpy(&my_mainloop_api, api, sizeof(my_mainloop_api));
+ return;
}
-static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
+static void autobridgeMainloopAPI(x64emu_t* emu, bridge_t* bridge, my_pa_mainloop_api_t* api)
{
if(!api) {
return;
}
- #define GO(A, W) my_mainloop_native.A = api->A; if(api->A) {my_mainloop_api.A = (void*)AddCheckBridge(bridge, W, native_##A, 0, NULL); api->A=my_##A;} else my_mainloop_api.A = NULL
+ #define GO(A, W) if(api->A) AddAutomaticBridge(emu, bridge, W, api->A, 0, NULL)
GO(io_new, pFpiipp);
GO(io_enable, vFpi);
GO(io_free, vFp);
@@ -1009,9 +1091,7 @@ static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
GO(defer_set_destroy, vFpp);
GO(quit, vFpi);
#undef GO
- my_mainloop_api.data = api->data;
- my_mainloop_orig = api;
- my_mainloop_ref = &my_mainloop_api;
+ memcpy(&my_mainloop_api, api, sizeof(my_mainloop_api));
return;
}
/*static my_pa_mainloop_api_t* backMainloopAPI(my_pa_mainloop_api_t* mainloop)
@@ -1029,45 +1109,41 @@ static void bridgeMainloopAPI(bridge_t* bridge, my_pa_mainloop_api_t* api)
EXPORT void my_pa_mainloop_free(x64emu_t* emu, void* mainloop)
{
my->pa_mainloop_free(mainloop);
- mainloop_inited = 0;
- /*my_mainloop_ref =*/ my_mainloop_orig = NULL;
}
EXPORT void* my_pa_mainloop_get_api(x64emu_t* emu, void* mainloop)
{
my_pa_mainloop_api_t* api = my->pa_mainloop_get_api(mainloop);
- bridgeMainloopAPI(my_lib->w.bridge, api);
- return my_mainloop_ref;
+ autobridgeMainloopAPI(emu, my_lib->w.bridge, api);
+ return api;
}
EXPORT void my_pa_threaded_mainloop_free(x64emu_t* emu, void* mainloop)
{
my->pa_threaded_mainloop_free(mainloop);
- mainloop_inited = 0;
- /*my_mainloop_ref =*/ my_mainloop_orig = NULL;
}
EXPORT void* my_pa_threaded_mainloop_get_api(x64emu_t* emu, void* mainloop)
{
my_pa_mainloop_api_t* api = my->pa_threaded_mainloop_get_api(mainloop);
- bridgeMainloopAPI(my_lib->w.bridge, api);
- return my_mainloop_ref;
+ autobridgeMainloopAPI(emu, my_lib->w.bridge, api);
+ return api;
}
// Context functions
EXPORT void* my_pa_context_new(x64emu_t* emu, my_pa_mainloop_api_t* mainloop, void* name)
{
- if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig; // need native version
+ UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
return my->pa_context_new(mainloop, name);
}
EXPORT void* my_pa_context_new_with_proplist(x64emu_t* emu, my_pa_mainloop_api_t* mainloop, void* name, void* proplist)
{
- if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig; // need native version
+ UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
return my->pa_context_new_with_proplist(mainloop, name, proplist);
}
EXPORT int my_pa_signal_init(x64emu_t* emu, my_pa_mainloop_api_t* mainloop)
{
- if(mainloop==my_mainloop_ref) mainloop=my_mainloop_orig; // need native version
+ UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
return my->pa_signal_init(mainloop);
}
@@ -1487,6 +1563,18 @@ EXPORT void* my_pa_context_get_source_output_info(x64emu_t* emu, void* c, uint32
{
return my->pa_context_get_source_output_info(c, idx, find_source_output_info_Fct(cb), data);
}
+
+EXPORT void* my_pa_context_rttime_new(x64emu_t* emu, void* c, uint64_t usec, void* cb, void* data)
+{
+ return my->pa_context_rttime_new(c, usec, findTimeEventFct(cb) ,data);
+}
+
+EXPORT void my_pa_mainloop_api_once(x64emu_t* emu, void* mainloop, void* cb, void* data)
+{
+ UpdateautobridgeMainloopAPI(emu, my_lib->w.bridge, mainloop);
+ my->pa_mainloop_api_once(mainloop, find_mainloop_once_Fct(cb), data);
+}
+
#define PRE_INIT \
if(box64_nopulse) \
return -1;
diff --git a/src/wrapped/wrappedpulse_private.h b/src/wrapped/wrappedpulse_private.h
index bceeaac..e345718 100644
--- a/src/wrapped/wrappedpulse_private.h
+++ b/src/wrapped/wrappedpulse_private.h
@@ -6,7 +6,7 @@ GO(pa_ascii_filter, pFp)
GO(pa_ascii_valid, pFp)
GO(pa_bytes_per_second, LFp)
GO(pa_bytes_snprint, pFpLu)
-GO(pa_bytes_to_usec, LFLp)
+GO(pa_bytes_to_usec, UFUp)
GO(pa_channel_map_can_balance, iFp)
GO(pa_channel_map_can_fade, iFp)
GO(pa_channel_map_compatible, iFpp)
@@ -79,6 +79,7 @@ GO(pa_context_ref, pFp)
//GO(pa_context_remove_autoload_by_index,
//GO(pa_context_remove_autoload_by_name,
//GO(pa_context_remove_sample,
+GOM(pa_context_rttime_new, pFEpUpp)
GOM(pa_context_set_card_profile_by_index, pFEpuppp)
//GO(pa_context_set_card_profile_by_name,
GOM(pa_context_set_default_sink, pFEpppp)
@@ -145,7 +146,7 @@ GO(pa_get_library_version, pFv)
GO(pa_gettimeofday, pFp)
GO(pa_get_user_name, pFpL)
//GO(pa_locale_to_utf8,
-//GO(pa_mainloop_api_once,
+GOM(pa_mainloop_api_once, vFEppp)
GO(pa_mainloop_dispatch, iFp)
GOM(pa_mainloop_free, vFEp)
GOM(pa_mainloop_get_api, pFEp)
@@ -184,6 +185,7 @@ GO(pa_proplist_to_string_sep, pFpp)
GO(pa_proplist_unset, iFpp)
GO(pa_proplist_unset_many, iFpp)
GO(pa_proplist_update, vFpup)
+GO(pa_rtclock_now, UFv)
GO(pa_sample_format_to_string, pFi)
GO(pa_sample_size, LFp)
GO(pa_sample_size_of_format, LFi)
@@ -273,11 +275,11 @@ GO(pa_threaded_mainloop_wait, vFp)
GO(pa_timeval_add, pFpU)
GO(pa_timeval_age, UFp)
GO(pa_timeval_cmp, iFpp)
-GO(pa_timeval_diff, LFpp)
-GO(pa_timeval_load, LFp)
-GO(pa_timeval_store, pFpL)
+GO(pa_timeval_diff, UFpp)
+GO(pa_timeval_load, UFp)
+GO(pa_timeval_store, pFpU)
GO(pa_timeval_sub, pFpU)
-GO(pa_usec_to_bytes, LFLp)
+GO(pa_usec_to_bytes, LFUp)
GO(pa_utf8_filter, pFp)
GO(pa_utf8_to_locale, pFp)
GO(pa_utf8_valid, pFp)
diff --git a/src/wrapped/wrappedpulsesimple.c b/src/wrapped/wrappedpulsesimple.c
index 1fd5681..c068505 100644
--- a/src/wrapped/wrappedpulsesimple.c
+++ b/src/wrapped/wrappedpulsesimple.c
@@ -17,15 +17,25 @@
#include "librarian.h"
#include "myalign.h"
-const char* pulsesimpleName = "libpulse-simple.so.0";
+#ifdef ANDROID
+ const char* pulsesimpleName = "libpulse-simple.so";
+#else
+ const char* pulsesimpleName = "libpulse-simple.so.0";
+#endif
+
#define LIBNAME pulsesimple
#define PRE_INIT \
if(box64_nopulse) \
return -1;
-#define CUSTOM_INIT \
- setNeededLibs(lib, 1, "libpulse.so.0");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 1, "libpulse.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 1, "libpulse.so.0");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedsdl1.c b/src/wrapped/wrappedsdl1.c
index 50f3e1b..b38a3fd 100644
--- a/src/wrapped/wrappedsdl1.c
+++ b/src/wrapped/wrappedsdl1.c
@@ -73,7 +73,7 @@ GO(4)
static uintptr_t my_AudioCallback_fct_##A = 0; \
static void my_AudioCallback_##A(void *userdata, uint8_t *stream, int32_t len) \
{ \
- RunFunctionFmt(my_AudioCallback_fct_##A, "pCi", userdata, stream, len); \
+ RunFunctionFmt(my_AudioCallback_fct_##A, "ppi", userdata, stream, len); \
}
SUPER()
#undef GO
diff --git a/src/wrapped/wrappedsdl2.c b/src/wrapped/wrappedsdl2.c
index 8f0710f..cf74511 100644
--- a/src/wrapped/wrappedsdl2.c
+++ b/src/wrapped/wrappedsdl2.c
@@ -799,10 +799,11 @@ EXPORT void* my2_SDL_Vulkan_GetVkGetInstanceProcAddr(x64emu_t* emu)
return NULL;
}
-EXPORT void my2_SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, uint16_t *vend, uint16_t *prod, uint16_t *ver)
+EXPORT void my2_SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, uint16_t *vend, uint16_t *prod, uint16_t *ver, uint16_t* crc16)
{
+ uint16_t dummy = 0;
if(my->SDL_GetJoystickGUIDInfo)
- my->SDL_GetJoystickGUIDInfo(guid, vend, prod, ver);
+ my->SDL_GetJoystickGUIDInfo(guid, vend, prod, ver, box64_sdl2_jguid?(&dummy):crc16);
// fallback
else {
uint16_t *guid16 = (uint16_t *)guid.data;
diff --git a/src/wrapped/wrappedsdl2_private.h b/src/wrapped/wrappedsdl2_private.h
index 6696fab..987737a 100644
--- a/src/wrapped/wrappedsdl2_private.h
+++ b/src/wrapped/wrappedsdl2_private.h
@@ -202,7 +202,7 @@ GO(SDL_GetGlobalMouseState, uFpp)
GO(SDL_GetGrabbedWindow, pFv)
GO(SDL_GetHint, pFp)
GO(SDL_GetHintBoolean, uFpu)
-GOM(SDL_GetJoystickGUIDInfo, vFGppp)
+GOM(SDL_GetJoystickGUIDInfo, vFGpppp)
GO(SDL_GetKeyboardFocus, pFv)
GO(SDL_GetKeyboardState, pFp)
GO(SDL_GetKeyFromName, iFp)
@@ -522,6 +522,7 @@ GO(SDL_RenderSetLogicalSize, iFpii)
GO(SDL_RenderSetScale, iFpff)
GO(SDL_RenderSetViewport, iFpp)
GO(SDL_RenderTargetSupported, iFp)
+GO(SDL_RenderWindowToLogical, vFpiipp)
GO(SDL_ReportAssertion, uFpppi)
GO(SDL_ResetAssertionReport, vFv)
GO(SDL_ResetKeyboard, vFv)
@@ -574,6 +575,7 @@ GO(SDL_SetRenderDrawColor, iFpCCCC)
GO(SDL_SetRenderTarget, iFpp)
GO(SDL_SetSurfaceAlphaMod, iFpC)
GO(SDL_SetSurfaceBlendMode, iFpu)
+GO(SDL_SetSurfaceColorMod, iFpCCC)
// SDL_SetSurfaceColorMod
GO(SDL_SetSurfacePalette, iFpp)
GO(SDL_SetSurfaceRLE, iFpi)
diff --git a/src/wrapped/wrappedtcmallocminimal_private.h b/src/wrapped/wrappedtcmallocminimal_private.h
index b1f6b1e..ce2b019 100644
--- a/src/wrapped/wrappedtcmallocminimal_private.h
+++ b/src/wrapped/wrappedtcmallocminimal_private.h
@@ -69,8 +69,8 @@ GO(malloc_stats, vFv)
GO(malloc_usable_size, LFp)
GO(mallopt, iFii)
GO(memalign, pFuu)
-GOM(mmap, pFEpLiiii) // use the my_mmap from wrappedlibc.c
-GOM(mmap64, pFEpLiiiI)
+GOM(mmap, pFEpLiiil) // use the my_mmap from wrappedlibc.c
+GOM(mmap64, pFEpLiiil)
GO(mremap, pFpuuip)
GOM(munmap, iFEpL)
GO(nallocx, LFLi)
diff --git a/src/wrapped/wrappedtermuxexec.c b/src/wrapped/wrappedtermuxexec.c
new file mode 100644
index 0000000..a3336b5
--- /dev/null
+++ b/src/wrapped/wrappedtermuxexec.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+
+const char* termuxexecName = "libtermux-exec.so";
+
+#define LIBNAME termuxexec
+
+#define CUSTOM_INIT \
+ setNeededLibs(lib, 1, "libc.so");
+
+#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedtermuxexec_private.h b/src/wrapped/wrappedtermuxexec_private.h
new file mode 100644
index 0000000..a0ed8e1
--- /dev/null
+++ b/src/wrapped/wrappedtermuxexec_private.h
@@ -0,0 +1,4 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA) && defined(GOS))
+#error Meh...
+#endif
+
diff --git a/src/wrapped/wrappedvorbisfile.c b/src/wrapped/wrappedvorbisfile.c
index 411a3ee..af91266 100644
--- a/src/wrapped/wrappedvorbisfile.c
+++ b/src/wrapped/wrappedvorbisfile.c
@@ -18,7 +18,12 @@
#include "myalign.h"
#include "bridge.h"
-const char* vorbisfileName = "libvorbisfile.so.3";
+#ifdef ANDROID
+ const char* vorbisfileName = "libvorbisfile.so";
+#else
+ const char* vorbisfileName = "libvorbisfile.so.3";
+#endif
+
#define LIBNAME vorbisfile
typedef struct {
diff --git a/src/wrapped/wrappedvulkan.c b/src/wrapped/wrappedvulkan.c
index 8cba577..02a729b 100644
--- a/src/wrapped/wrappedvulkan.c
+++ b/src/wrapped/wrappedvulkan.c
@@ -34,26 +34,21 @@ typedef void(*vFpUp_t) (void*, uint64_t, void*);
#define ADDED_SUPER 1
#include "wrappercallback.h"
-void updateInstance(vulkan_my_t* my)
+static void updateInstance(x64emu_t* emu, vulkan_my_t* my)
{
void* p;
#define GO(A, W) p = my_context->vkprocaddress(my->currentInstance, #A); if(p) my->A = p;
SUPER()
#undef GO
+ symbol1_t* s;
+ kh_foreach_value_ref(emu->context->vkwrappers, s, s->resolved = 0;)
}
void fillVulkanProcWrapper(box64context_t*);
void freeVulkanProcWrapper(box64context_t*);
-static void* resolveSymbol(x64emu_t* emu, void* symbol, const char* rname)
+static symbol1_t* getWrappedSymbol(x64emu_t* emu, const char* rname, int warning)
{
- // check if alread bridged
- uintptr_t ret = CheckBridged(emu->context->system, symbol);
- if(ret) {
- printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret);
- return (void*)ret; // already bridged
- }
- // get wrapper
khint_t k = kh_get(symbolmap, emu->context->vkwrappers, rname);
if(k==kh_end(emu->context->vkwrappers) && strstr(rname, "KHR")==NULL) {
// try again, adding KHR at the end if not present
@@ -63,15 +58,28 @@ static void* resolveSymbol(x64emu_t* emu, void* symbol, const char* rname)
k = kh_get(symbolmap, emu->context->vkwrappers, tmp);
}
if(k==kh_end(emu->context->vkwrappers)) {
- printf_dlsym(LOG_DEBUG, "%p\n", NULL);
- printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname);
+ if(warning) {
+ printf_dlsym(LOG_DEBUG, "%p\n", NULL);
+ printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname);
+ }
return NULL;
}
- const char* constname = kh_key(emu->context->vkwrappers, k);
- AddOffsetSymbol(emu->context->maplib, symbol, constname);
- ret = AddBridge(emu->context->system, kh_value(emu->context->vkwrappers, k), symbol, 0, constname);
- printf_dlsym(LOG_DEBUG, "%p (%p)\n", (void*)ret, symbol);
- return (void*)ret;
+ return &kh_value(emu->context->vkwrappers, k);
+}
+
+static void* resolveSymbol(x64emu_t* emu, void* symbol, const char* rname)
+{
+ // get wrapper
+ symbol1_t *s = getWrappedSymbol(emu, rname, 1);
+ if(!s->resolved) {
+ khint_t k = kh_get(symbolmap, emu->context->vkwrappers, rname);
+ const char* constname = kh_key(emu->context->vkwrappers, k);
+ s->addr = AddBridge(emu->context->system, s->w, symbol, 0, constname);
+ s->resolved = 1;
+ }
+ void* ret = (void*)s->addr;
+ printf_dlsym(LOG_DEBUG, "%p (%p)\n", ret, symbol);
+ return ret;
}
EXPORT void* my_vkGetDeviceProcAddr(x64emu_t* emu, void* device, void* name)
@@ -82,6 +90,12 @@ EXPORT void* my_vkGetDeviceProcAddr(x64emu_t* emu, void* device, void* name)
printf_dlsym(LOG_DEBUG, "Calling my_vkGetDeviceProcAddr(%p, \"%s\") => ", device, rname);
if(!emu->context->vkwrappers)
fillVulkanProcWrapper(emu->context);
+ symbol1_t* s = getWrappedSymbol(emu, rname, 0);
+ if(s && s->resolved) {
+ void* ret = (void*)s->addr;
+ printf_dlsym(LOG_DEBUG, "%p (cached)\n", ret);
+ return ret;
+ }
k = kh_get(symbolmap, emu->context->vkmymap, rname);
int is_my = (k==kh_end(emu->context->vkmymap))?0:1;
void* symbol = my->vkGetDeviceProcAddr(device, name);
@@ -113,7 +127,13 @@ EXPORT void* my_vkGetInstanceProcAddr(x64emu_t* emu, void* instance, void* name)
fillVulkanProcWrapper(emu->context);
if(instance!=my->currentInstance) {
my->currentInstance = instance;
- updateInstance(my);
+ updateInstance(emu, my);
+ }
+ symbol1_t* s = getWrappedSymbol(emu, rname, 0);
+ if(s && s->resolved) {
+ void* ret = (void*)s->addr;
+ printf_dlsym(LOG_DEBUG, "%p (cached)\n", ret);
+ return ret;
}
// check if vkprocaddress is filled, and search for lib and fill it if needed
// get proc adress using actual glXGetProcAddress
@@ -146,6 +166,12 @@ void* my_GetVkProcAddr(x64emu_t* emu, void* name, void*(*getaddr)(const char*))
printf_dlsym(LOG_DEBUG, "Calling my_GetVkProcAddr(\"%s\", %p) => ", rname, getaddr);
if(!emu->context->vkwrappers)
fillVulkanProcWrapper(emu->context);
+ symbol1_t* s = getWrappedSymbol(emu, rname, 0);
+ if(s && s->resolved) {
+ void* ret = (void*)s->addr;
+ printf_dlsym(LOG_DEBUG, "%p (cached)\n", ret);
+ return ret;
+ }
// check if vkprocaddress is filled, and search for lib and fill it if needed
// get proc adress using actual glXGetProcAddress
k = kh_get(symbolmap, emu->context->vkmymap, rname);
@@ -181,6 +207,28 @@ typedef struct my_VkAllocationCallbacks_s {
void* pfnInternalFree;
} my_VkAllocationCallbacks_t;
+typedef struct my_VkDebugUtilsMessengerCreateInfoEXT_s {
+ int sType;
+ const void* pNext;
+ int flags;
+ int messageSeverity;
+ int messageType;
+ void* pfnUserCallback;
+ void* pUserData;
+} my_VkDebugUtilsMessengerCreateInfoEXT_t;
+
+typedef struct my_VkDebugReportCallbackCreateInfoEXT_s {
+ int sType;
+ const void* pNext;
+ int flags;
+ void* pfnCallback;
+ void* pUserData;
+} my_VkDebugReportCallbackCreateInfoEXT_t;
+
+typedef struct my_VkStruct_s {
+ int sType;
+ struct my_VkStruct_s* pNext;
+} my_VkStruct_t;
#define SUPER() \
GO(0) \
@@ -321,6 +369,28 @@ static void* find_DebugReportCallbackEXT_Fct(void* fct)
printf_log(LOG_NONE, "Warning, no more slot for Vulkan DebugReportCallbackEXT callback\n");
return NULL;
}
+// DebugUtilsMessengerCallback ...
+#define GO(A) \
+static uintptr_t my_DebugUtilsMessengerCallback_fct_##A = 0; \
+static int my_DebugUtilsMessengerCallback_##A(int a, int b, void* c, void* d) \
+{ \
+ return RunFunctionFmt(my_DebugUtilsMessengerCallback_fct_##A, "iipp", a, b, c, d); \
+}
+SUPER()
+#undef GO
+static void* find_DebugUtilsMessengerCallback_Fct(void* fct)
+{
+ if(!fct) return fct;
+ if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
+ #define GO(A) if(my_DebugUtilsMessengerCallback_fct_##A == (uintptr_t)fct) return my_DebugUtilsMessengerCallback_##A;
+ SUPER()
+ #undef GO
+ #define GO(A) if(my_DebugUtilsMessengerCallback_fct_##A == 0) {my_DebugUtilsMessengerCallback_fct_##A = (uintptr_t)fct; return my_DebugUtilsMessengerCallback_##A; }
+ SUPER()
+ #undef GO
+ printf_log(LOG_NONE, "Warning, no more slot for Vulkan DebugUtilsMessengerCallback callback\n");
+ return NULL;
+}
#undef SUPER
@@ -349,13 +419,15 @@ void fillVulkanProcWrapper(box64context_t* context)
cnt = sizeof(vulkansymbolmap)/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, vulkansymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = vulkansymbolmap[i].w;
+ kh_value(symbolmap, k).w = vulkansymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
// and the my_ symbols map
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, vulkanmysymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = vulkanmysymbolmap[i].w;
+ kh_value(symbolmap, k).w = vulkanmysymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
context->vkwrappers = symbolmap;
// my_* map
@@ -363,7 +435,8 @@ void fillVulkanProcWrapper(box64context_t* context)
cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t);
for (int i=0; i<cnt; ++i) {
k = kh_put(symbolmap, symbolmap, vulkanmysymbolmap[i].name, &ret);
- kh_value(symbolmap, k) = vulkanmysymbolmap[i].w;
+ kh_value(symbolmap, k).w = vulkanmysymbolmap[i].w;
+ kh_value(symbolmap, k).resolved = 0;
}
context->vkmymap = symbolmap;
}
@@ -449,10 +522,46 @@ EXPORT int my_vkCreateGraphicsPipelines(x64emu_t* emu, void* device, uint64_t pi
CREATE(vkCreateImage)
CREATE(vkCreateImageView)
+#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT 1000011000
+#define VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT 1000128004
EXPORT int my_vkCreateInstance(x64emu_t* emu, void* pCreateInfos, my_VkAllocationCallbacks_t* pAllocator, void* pInstance)
{
my_VkAllocationCallbacks_t my_alloc;
- return my->vkCreateInstance(pCreateInfos, find_VkAllocationCallbacks(&my_alloc, pAllocator), pInstance);
+ my_VkStruct_t *p = (my_VkStruct_t*)pCreateInfos;
+ void* old[20] = {0};
+ int old_i = 0;
+ while(p) {
+ if(p->sType==VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT) {
+ my_VkDebugReportCallbackCreateInfoEXT_t* vk = (my_VkDebugReportCallbackCreateInfoEXT_t*)p;
+ old[old_i] = vk->pfnCallback;
+ vk->pfnCallback = find_DebugReportCallbackEXT_Fct(old[old_i]);
+ old_i++;
+ } else if(p->sType==VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ my_VkDebugUtilsMessengerCreateInfoEXT_t* vk = (my_VkDebugUtilsMessengerCreateInfoEXT_t*)p;
+ old[old_i] = vk->pfnUserCallback;
+ vk->pfnUserCallback = find_DebugUtilsMessengerCallback_Fct(old[old_i]);
+ old_i++;
+ }
+ p = p->pNext;
+ }
+ int ret = my->vkCreateInstance(pCreateInfos, find_VkAllocationCallbacks(&my_alloc, pAllocator), pInstance);
+ if(old_i) {// restore, just in case it's re-used?
+ p = (my_VkStruct_t*)pCreateInfos;
+ old_i = 0;
+ while(p) {
+ if(p->sType==VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT) {
+ my_VkDebugReportCallbackCreateInfoEXT_t* vk = (my_VkDebugReportCallbackCreateInfoEXT_t*)p;
+ vk->pfnCallback = old[old_i];
+ old_i++;
+ } else if(p->sType==VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ my_VkDebugUtilsMessengerCreateInfoEXT_t* vk = (my_VkDebugUtilsMessengerCreateInfoEXT_t*)p;
+ vk->pfnUserCallback = old[old_i];
+ old_i++;
+ }
+ p = p->pNext;
+ }
+ }
+ return ret;
}
CREATE(vkCreatePipelineCache)
@@ -530,7 +639,17 @@ DESTROY64(vkDestroySwapchainKHR)
DESTROY64(vkFreeMemory)
-CREATE(vkCreateDebugUtilsMessengerEXT)
+EXPORT int my_vkCreateDebugUtilsMessengerEXT(x64emu_t* emu, void* device, my_VkDebugUtilsMessengerCreateInfoEXT_t* pAllocateInfo, my_VkAllocationCallbacks_t* pAllocator, void* p)
+{
+ #define VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT 1000128004
+ my_VkAllocationCallbacks_t my_alloc;
+ my_VkDebugUtilsMessengerCreateInfoEXT_t* info = pAllocateInfo;
+ while(info && info->sType==VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ info->pfnUserCallback = find_DebugUtilsMessengerCallback_Fct(info->pfnUserCallback);
+ info = (my_VkDebugUtilsMessengerCreateInfoEXT_t*)info->pNext;
+ }
+ return my->vkCreateDebugUtilsMessengerEXT(device, pAllocateInfo, find_VkAllocationCallbacks(&my_alloc, pAllocator), p);
+}
DESTROY(vkDestroyDebugUtilsMessengerEXT)
DESTROY64(vkDestroySurfaceKHR)
@@ -585,6 +704,10 @@ DESTROY64(vkDestroyAccelerationStructureNV)
CREATE(vkCreateOpticalFlowSessionNV)
DESTROY64(vkDestroyOpticalFlowSessionNV)
+CREATE(vkCreateMicromapEXT)
+DESTROY64(vkDestroyMicromapEXT)
+
+
EXPORT void my_vkGetPhysicalDeviceProperties(x64emu_t* emu, void* device, void* pProps)
{
my->vkGetPhysicalDeviceProperties(device, pProps);
@@ -623,14 +746,6 @@ EXPORT void my_vkCmdPipelineBarrier(x64emu_t* emu, void* device, int src, int ds
my->vkCmdPipelineBarrier(device, src, dst, dep, barrierCount, pBarriers, bufferCount, pBuffers, imageCount, pImages);
}
-typedef struct my_VkDebugReportCallbackCreateInfoEXT_s {
- int sType;
- void* pNext;
- uint32_t flags;
- void* pfnCallback;
- void* pUserData;
-} my_VkDebugReportCallbackCreateInfoEXT_t;
-
EXPORT int my_vkCreateDebugReportCallbackEXT(x64emu_t* emu, void* instance,
my_VkDebugReportCallbackCreateInfoEXT_t* create,
my_VkAllocationCallbacks_t* alloc, void* callback)
diff --git a/src/wrapped/wrappedvulkan_private.h b/src/wrapped/wrappedvulkan_private.h
index 96ee093..17254bc 100644
--- a/src/wrapped/wrappedvulkan_private.h
+++ b/src/wrapped/wrappedvulkan_private.h
@@ -267,7 +267,7 @@ GO(vkDebugReportMessageEXT, vFpiiULipp)
GOM(vkDestroyDebugReportCallbackEXT, iFEppp)
//VK_EXT_debug_utils
-GO(vkCmdBeginDebugUtilsLabelEXT, vFpp) //TODO: Cehck alignement of this extension
+GO(vkCmdBeginDebugUtilsLabelEXT, vFpp) //TODO: Check alignement of this extension
GO(vkCmdEndDebugUtilsLabelEXT, vFp)
GO(vkCmdInsertDebugUtilsLabelEXT, vFpp)
GOM(vkCreateDebugUtilsMessengerEXT, iFEpppp)
@@ -277,7 +277,7 @@ GO(vkQueueEndDebugUtilsLabelEXT, vFp)
GO(vkQueueInsertDebugUtilsLabelEXT, vFpp)
GO(vkSetDebugUtilsObjectNameEXT, iFpp)
GO(vkSetDebugUtilsObjectTagEXT, iFpp)
-//GOM(vkSubmitDebugUtilsMessageEXT, vFEpppp) // callback in last arguments
+GO(vkSubmitDebugUtilsMessageEXT, vFpppp)
// VK_KHR_external_memory_capabilities
GO(vkGetPhysicalDeviceExternalBufferPropertiesKHR, vFppp)
@@ -829,3 +829,40 @@ GO(vkGetDescriptorSetLayoutSizeEXT, vFpUp)
GO(vkGetImageOpaqueCaptureDescriptorDataEXT, vFppp)
GO(vkGetImageViewOpaqueCaptureDescriptorDataEXT, vFppp)
GO(vkGetSamplerOpaqueCaptureDescriptorDataEXT, vFppp)
+
+// VK_KHR_cooperative_matrix
+GO(vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR, iFppp)
+
+// VK_KHR_maintenance5
+GO(vkCmdBindIndexBuffer2KHR, vFpUUUi)
+GO(vkGetDeviceImageSubresourceLayoutKHR, vFppp)
+GO(vkGetImageSubresourceLayout2KHR, vFpUpp)
+GO(vkGetRenderingAreaGranularityKHR, vFppp)
+
+// VK_NV_memory_decompression
+GO(vkCmdDecompressMemoryIndirectCountNV, vFpUUu)
+GO(vkCmdDecompressMemoryNV, vFpup)
+
+// VK_EXT_merge_shader
+GO(vkCmdDrawMeshTasksEXT, vFpuuu)
+GO(vkCmdDrawMeshTasksIndirectCountEXT, vFpUUUUuu)
+GO(vkCmdDrawMeshTasksIndirectEXT, vFpUUuu)
+
+// VK_EXT_opacity_micromap
+GO(vkBuildMicromapsEXT, iFpiup)
+GO(vkCmdBuildMicromapsEXT, vFpup)
+GO(vkCmdCopyMemoryToMicromapEXT, vFpp)
+GO(vkCmdCopyMicromapEXT, vFpp)
+GO(vkCmdCopyMicromapToMemoryEXT, vFpp)
+GO(vkCmdWriteMicromapsPropertiesEXT, vFpupiUu)
+GO(vkCopyMemoryToMicromapEXT, iFpUp)
+GO(vkCopyMicromapEXT, iFpUp)
+GO(vkCopyMicromapToMemoryEXT, iFpUp)
+GOM(vkCreateMicromapEXT, iFEpppp)
+GOM(vkDestroyMicromapEXT, vFEpUp)
+GO(vkGetDeviceMicromapCompatibilityEXT, vFppp)
+GO(vkGetMicromapBuildSizesEXT, vFpipp)
+GO(vkWriteMicromapsPropertiesEXT, iFpupiLpL)
+
+// VK_KHR_ray_tracing_maintenance1
+GO(vkCmdTraceRaysIndirect2KHR, vFpU) \ No newline at end of file
diff --git a/src/wrapped/wrappedwaylandclient_private.h b/src/wrapped/wrappedwaylandclient_private.h
index 1d54f28..3a04a73 100644
--- a/src/wrapped/wrappedwaylandclient_private.h
+++ b/src/wrapped/wrappedwaylandclient_private.h
@@ -8,7 +8,7 @@
//GO(wl_array_release,
//DATA(wl_buffer_interface,
//DATA(wl_callback_interface,
-//DATA(wl_compositor_interface,
+DATA(wl_compositor_interface, sizeof(void*)*3+sizeof(int)*4)
//DATA(wl_data_device_interface,
//DATA(wl_data_device_manager_interface,
//DATA(wl_data_offer_interface,
@@ -26,14 +26,14 @@ GO(wl_display_flush, iFp)
GO(wl_display_get_error, iFp)
GO(wl_display_get_fd, iFp)
//GO(wl_display_get_protocol_error,
-//DATA(wl_display_interface,
+DATA(wl_display_interface, sizeof(void*)*3+sizeof(int)*4)
GO(wl_display_prepare_read, iFp)
GO(wl_display_prepare_read_queue, iFpp)
GO(wl_display_read_events, iFp)
GO(wl_display_roundtrip, iFp)
-//GO(wl_display_roundtrip_queue,
+GO(wl_display_roundtrip_queue, iFpp)
GO(wl_event_queue_destroy, vFp)
-//DATA(wl_keyboard_interface,
+DATA(wl_keyboard_interface, sizeof(void*)*3+sizeof(int)*4)
//GO(wl_list_empty,
//GO(wl_list_init,
//GO(wl_list_insert,
@@ -41,8 +41,8 @@ GO(wl_event_queue_destroy, vFp)
//GO(wl_list_length,
//GO(wl_list_remove,
//GO(wl_log_set_handler_client,
-//DATA(wl_output_interface,
-//DATA(wl_pointer_interface,
+DATA(wl_output_interface, sizeof(void*)*3+sizeof(int)*4)
+DATA(wl_pointer_interface, sizeof(void*)*3+sizeof(int)*4)
//GO(wl_proxy_add_dispatcher,
GO(wl_proxy_add_listener, iFppp)
GO(wl_proxy_create, pFpp)
@@ -54,13 +54,13 @@ GO(wl_proxy_get_listener, pFp)
//GO(wl_proxy_get_tag,
GO(wl_proxy_get_user_data, pFp)
GO(wl_proxy_get_version, uFp)
-//GO(wl_proxy_marshal,
-//GO(wl_proxy_marshal_array,
+GO(wl_proxy_marshal, vFpupppppppppp) //VAARGS
+GO(wl_proxy_marshal_array, vFpup)
GO(wl_proxy_marshal_array_constructor, pFpupp)
GO(wl_proxy_marshal_array_constructor_versioned, pFpuppu)
//GO(wl_proxy_marshal_array_flags,
-//GO(wl_proxy_marshal_constructor,
-//GO(wl_proxy_marshal_constructor_versioned,
+GO(wl_proxy_marshal_constructor, pFpupppppppppppppppp) //VAARGS
+GO(wl_proxy_marshal_constructor_versioned, pFpupupppppppppppppppp) //VAARGS
//GO(wl_proxy_marshal_flags,
GO(wl_proxy_set_queue, vFpp)
//GO(wl_proxy_set_tag,
diff --git a/src/wrapped/wrappedxinerama.c b/src/wrapped/wrappedxinerama.c
index fed2403..eeebec4 100644
--- a/src/wrapped/wrappedxinerama.c
+++ b/src/wrapped/wrappedxinerama.c
@@ -11,11 +11,21 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* xineramaName = "libXinerama.so.1";
+#ifdef ANDROID
+ const char* xineramaName = "libXinerama.so";
+#else
+ const char* xineramaName = "libXinerama.so.1";
+#endif
+
#define LIBNAME xinerama
-#define CUSTOM_INIT \
- setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#ifdef ANDROID
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so", "libXext.so");
+#else
+ #define CUSTOM_INIT \
+ setNeededLibs(lib, 2, "libX11.so.6", "libXext.so.6");
+#endif
#include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedxkbcommon_private.h b/src/wrapped/wrappedxkbcommon_private.h
index 6d4a3dc..ccbc71e 100644
--- a/src/wrapped/wrappedxkbcommon_private.h
+++ b/src/wrapped/wrappedxkbcommon_private.h
@@ -33,7 +33,7 @@ GO(xkb_context_set_log_level, vFpi)
GO(xkb_context_set_log_verbosity, vFpi)
GO(xkb_context_set_user_data, vFpp)
GO(xkb_context_unref, vFp)
-//GO(xkb_keymap_get_as_string,
+GO(xkb_keymap_get_as_string, pFpi)
GO(xkb_keymap_key_by_name, uFpp)
//GOM(xkb_keymap_key_for_each, vFEppp)
GO(xkb_keymap_key_get_name, pFpu)
diff --git a/src/wrapped/wrappedxshmfence.c b/src/wrapped/wrappedxshmfence.c
index 64613bf..e6f83b8 100644
--- a/src/wrapped/wrappedxshmfence.c
+++ b/src/wrapped/wrappedxshmfence.c
@@ -11,7 +11,12 @@
#include "librarian/library_private.h"
#include "x64emu.h"
-const char* xshmfenceName = "libxshmfence.so.1";
+#ifdef ANDROID
+ const char* xshmfenceName = "libxshmfence.so";
+#else
+ const char* xshmfenceName = "libxshmfence.so.1";
+#endif
+
#define LIBNAME xshmfence
#include "wrappedlib_init.h"
diff --git a/system/box64.box64rc b/system/box64.box64rc
index ae2dfba..4df97ae 100644
--- a/system/box64.box64rc
+++ b/system/box64.box64rc
@@ -7,6 +7,7 @@
#
[3dSen.x86_64]
BOX64_DYNAREC_BLEEDING_EDGE=0 # avoid the use of STRONGMEM for much better performances
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[7z]
# Those are safe to use on 7z and give a bit of a boost
@@ -14,6 +15,7 @@ BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=512
BOX64_DYNAREC_CALLRET=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[7zz]
# Those are safe to use on 7z and give a bit of a boost
@@ -21,12 +23,19 @@ BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=512
BOX64_DYNAREC_CALLRET=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
+
+[bash]
+# LOG tend to mess up script execution in bash
+BOX64_LOG=0
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[chrome]
BOX64_MALLOC_HACK=2
[deadcells]
BOX64_PREFER_EMULATED=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[dontstarve]
# use emulated sdl2
@@ -45,12 +54,18 @@ BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=1024
BOX64_DYNAREC_CALLRET=1
BOX64_DYNAREC_FASTROUND=0
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
+
+[geekbench6]
+BOX64_ENV=BOX64_DYNAREC_STRONGMEM=3
[heroic]
BOX64_NOSANDBOX=1
+BOX64_INPROCESSGPU=1
BOX64_MALLOC_HACK=2
-# this is to save some memory
-BOX64_DYNAREC_BIGBLOCK=0
+#BOX64_DYNAREC_BIGBLOCK=0 # this is to save some memory, but not necessery with callret=1 (default)
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
+BOX64_DYNAREC_STRONGMEM=1
[LotCG.x86_64]
BOX64_DYNAREC_FASTROUND=0
@@ -61,23 +76,32 @@ BOX64_MALLOC_HACK=1
[NuclearBlaze]
BOX64_EMULATED_LIBS=libopenal.so.1
BOX64_DYNAREC_SAFEFLAGS=0
-BOX64_DYNAREC_BIGBLOCK=3
-BOX64_DYNAREC_FORWARD=1024
-#BOX64_DYNAREC_CALLRET=1 #New jmpbuf handling tend to break this optim!
+#BOX64_DYNAREC_BIGBLOCK=3
+#BOX64_DYNAREC_FORWARD=1024
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[pressure-vessel-wrap]
BOX64_NOGTK=1
[ProjectZomboid64]
# This one is still a bit unstable. This might help, but will also slowdown emulation
-BOX64_DYNAREC_STRONGMEM=2
+BOX64_DYNAREC_STRONGMEM=3
BOX64_DYNAREC_SAFEFLAGS=2
BOX64_DYNAREC_JVM=0
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[Soma.bin.x86_64]
# This is needed or the physics engine will not behave correctly
BOX64_DYNAREC_FASTROUND=0
+[spotify]
+BOX64_NOSANDBOX=1
+BOX64_INPROCESSGPU=1
+BOX64_DYNAREC_STRONGMEM=1
+BOX64_MALLOC_HACK=2
+# this is to save some memory
+BOX64_DYNAREC_BIGBLOCK=0
+
[steam]
BOX64_CRASHHANDLER=1
BOX64_EMULATED_LIBS=libudev.so.0
@@ -87,18 +111,26 @@ BOX64_EMULATED_LIBS=libSDL2-2.0.so.0:libSDL2_ttf-2.0.so.0
[steamwebhelper]
BOX64_NOSANDBOX=1
+BOX64_INPROCESSGPU=1
BOX64_LOG=0
BOX64_MALLOC_HACK=2
-# this is to save some memory
+#BOX64_DYNAREC_BIGBLOCK=0 # this is to save some memory
+BOX64_DYNAREC_STRONGMEM=1
+
+[steamwebhelper.exe]
BOX64_DYNAREC_BIGBLOCK=0
-# if steamwebhelper takes too much memory, enable next line to disable it
-#BOX64_EXIT=1
+BOX64_DYNAREC_STRONGMEM=1
[steam-runtime-check-requirements]
BOX64_EXIT=1
[steam-runtime-launcher-service]
BOX64_NOGTK=1
+BOX64_EXIT=1
+
+[ShovelKnight]
+BOX64_SDL2_JGUID=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
[Torchlight2.bin.x86_64]
# Those are safe to use on 7z and give a bit of a boost
@@ -106,18 +138,44 @@ BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_FORWARD=512
BOX64_DYNAREC_CALLRET=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
+
+[ToTheMoon.bin.x86_64]
+BOX64_PREFER_EMULATED=1
+
+[trine3_linux_64bit]
+BOX64_DYNAREC_STRONGMEM=1
[weixin]
BOX64_MALLOC_HACK=2
BOX64_NOSANDBOX=1
+BOX64_INPROCESSGPU=1
#
# Wine process
#
+[BatmanAK.exe]
+BOX64_DYNAREC_STRONGMEM=1
+BOX64_DYNAREC_ALIGNED_ATOMICS=1
+
[DOOMx64.exe]
BOX64_DYNAREC_SAFEFLAGS=0
[DOOMx64vk.exe]
BOX64_DYNAREC_SAFEFLAGS=0
+[Fallout4.exe]
+BOX64_DYNAREC_STRONGMEM=1
+
+[MMRX.exe]
+BOX64_DYNAREC_STRONGMEM=1
+
+[Sunblaze.exe]
+BOX64_DYNAREC_STRONGMEM=1
+
+[Risk of Rain 2.exe]
+BOX64_DYNAREC_STRONGMEM=1
+
+[witcher3.exe]
+BOX64_DYNAREC_STRONGMEM=1
diff --git a/tests/ref17.txt b/tests/ref17.txt
index 865dabc..35f59cd 100644
--- a/tests/ref17.txt
+++ b/tests/ref17.txt
@@ -538,3 +538,27 @@ cvtps2pd(1 2 3 -4 ) = 0x1 0x2 0x3 0xfffffffc
cvtps2pd(0 -2 -10 0.5 ) = 0x0 0xfffffffe 0xfffffff6 0x0
cvtps2pd(inf -inf -inf 1 ) = 0x80000000 0x80000000 0x80000000 0x1
cvtps2pd(nan -0 nan inf ) = 0x80000000 0x0 0x80000000 0x80000000
+dpps(1 2 3 -4 , 0 -2 -10 0.5 , 255) = -36 -36 -36 -36
+dpps(0 -2 -10 0.5 , inf -inf -inf 1 , 255) = nan nan nan nan
+dpps(1 2 3 -4 , nan -0 nan inf , 255) = nan nan nan nan
+dpps(0 -2 -10 0.5 , nan -0 nan inf , 255) = nan nan nan nan
+dpps(inf -inf -inf 1 , nan -0 nan inf , 255) = nan nan nan nan
+dpps(nan -0 nan inf , nan -0 nan inf , 255) = nan nan nan nan
+dpps(1 2 3 -4 , 0 -2 -10 0.5 , 63) = -4 -4 -4 -4
+dpps(0 -2 -10 0.5 , inf -inf -inf 1 , 63) = nan nan nan nan
+dpps(1 2 3 -4 , nan -0 nan inf , 63) = nan nan nan nan
+dpps(0 -2 -10 0.5 , nan -0 nan inf , 63) = nan nan nan nan
+dpps(inf -inf -inf 1 , nan -0 nan inf , 63) = nan nan nan nan
+dpps(nan -0 nan inf , nan -0 nan inf , 63) = nan nan nan nan
+dpps(1 2 3 -4 , 0 -2 -10 0.5 , 243) = -36 -36 0 0
+dpps(0 -2 -10 0.5 , inf -inf -inf 1 , 243) = nan nan 0 0
+dpps(1 2 3 -4 , nan -0 nan inf , 243) = nan nan 0 0
+dpps(0 -2 -10 0.5 , nan -0 nan inf , 243) = nan nan 0 0
+dpps(inf -inf -inf 1 , nan -0 nan inf , 243) = nan nan 0 0
+dpps(nan -0 nan inf , nan -0 nan inf , 243) = nan nan 0 0
+dpps(1 2 3 -4 , 0 -2 -10 0.5 , 83) = -30 -30 0 0
+dpps(0 -2 -10 0.5 , inf -inf -inf 1 , 83) = nan nan 0 0
+dpps(1 2 3 -4 , nan -0 nan inf , 83) = nan nan 0 0
+dpps(0 -2 -10 0.5 , nan -0 nan inf , 83) = nan nan 0 0
+dpps(inf -inf -inf 1 , nan -0 nan inf , 83) = nan nan 0 0
+dpps(nan -0 nan inf , nan -0 nan inf , 83) = nan nan 0 0
diff --git a/tests/ref23.txt b/tests/ref23.txt
new file mode 100644
index 0000000..b06138f
--- /dev/null
+++ b/tests/ref23.txt
@@ -0,0 +1 @@
+Res = 0xefcd00ef
diff --git a/tests/ref24.txt b/tests/ref24.txt
new file mode 100644
index 0000000..40df3e6
--- /dev/null
+++ b/tests/ref24.txt
@@ -0,0 +1,8 @@
+ret = 0xedefcdab78563412
+ret = 0x78563412
+ret = 0x3412
+ret = 0xedefcdab78563412
+ret = 0x78563412
+ret = 0x3412
+ret = 0x12345678abcdefed
+ret = 0x12345678
diff --git a/tests/ref25.txt b/tests/ref25.txt
new file mode 100644
index 0000000..374f79b
--- /dev/null
+++ b/tests/ref25.txt
@@ -0,0 +1,10 @@
+8.000000
+7.000000
+6.000000
+5.000000
+4.000000
+3.000000
+2.000000
+1.000000
+0.000000
+0.000000
diff --git a/tests/ref26.txt b/tests/ref26.txt
new file mode 100644
index 0000000..df60c72
--- /dev/null
+++ b/tests/ref26.txt
@@ -0,0 +1,640 @@
+Testing rint(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing rint(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing rint(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rint(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rint(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rint(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rint(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rint(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing rintf(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing rintf(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing rintf(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rintf(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rintf(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rintf(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rintf(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing rintf(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing nearbyint(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing nearbyint(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing nearbyint(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyint(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyint(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyint(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyint(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyint(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing nearbyintf(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing llrintf(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing llrintf(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing llrintf(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrintf(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrintf(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrintf(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrintf(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrintf(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing llrint(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing llrint(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing llrint(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrint(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrint(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrint(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrint(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing llrint(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing lrintf(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing lrintf(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing lrintf(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrintf(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrintf(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrintf(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrintf(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrintf(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
+Testing lrint(1.000000)
+FE_UPWARD: 1.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing lrint(1.300000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 1.0
+Current rounding mode: 0x0
+
+Testing lrint(1.500000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrint(1.800000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 1.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 1.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrint(2.000000)
+FE_UPWARD: 2.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrint(2.300000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrint(2.500000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 2.0
+Current rounding mode: 0x0
+
+Testing lrint(2.800000)
+FE_UPWARD: 3.0
+Current rounding mode: 0x800
+FE_DOWNWARD: 2.0
+Current rounding mode: 0x400
+FE_TOWARDZERO: 2.0
+Current rounding mode: 0xc00
+FE_TONEAREST: 3.0
+Current rounding mode: 0x0
+
diff --git a/tests/ref27.txt b/tests/ref27.txt
new file mode 100644
index 0000000..09cef0c
--- /dev/null
+++ b/tests/ref27.txt
@@ -0,0 +1,1063 @@
+test SSE 4.2
+_mm_cmpestri("This is a string", 16, "This", 4, 0x0) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x0) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x0) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x0) => 0
+_mm_cmpestri("This is a string", "This", 0x0) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x0) = 0000000000000000-000000000000000f
+_mm_cmpestri("This is a string", 16, "This", 4, 0x1) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x1) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x1) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x1) => 0
+_mm_cmpestri("This is a string", "This", 0x1) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x1) = 0000000000000000-000000000000000f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x0) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x0) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x0) = 0000000000000000-000000000000246f
+_mm_cmpistri("This", "This is a string", 0x0) => 0
+_mm_cmpestri("This", "This is a string", 0x0) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x0) = 0000000000000000-000000000000246f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x1) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x1) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x1) = 0000000000000000-000000000000006f
+_mm_cmpistri("This", "This is a string", 0x1) => 0
+_mm_cmpestri("This", "This is a string", 0x1) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x1) = 0000000000000000-000000000000006f
+_mm_cmpestri("This is a string", 16, "is", 2, 0x0) => 0
+_mm_cmpestri("This is a string", 16, "is", 2, 0x0) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "is", 2, 0x0) = 0000000000000000-0000000000000003
+_mm_cmpistri("This is a string", "is", 0x0) => 0
+_mm_cmpestri("This is a string", "is", 0x0) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "is", 0x0) = 0000000000000000-0000000000000003
+_mm_cmpestri("This is a string", 16, "is", 2, 0x1) => 0
+_mm_cmpestri("This is a string", 16, "is", 2, 0x1) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "is", 2, 0x1) = 0000000000000000-0000000000000003
+_mm_cmpistri("This is a string", "is", 0x1) => 0
+_mm_cmpestri("This is a string", "is", 0x1) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "is", 0x1) = 0000000000000000-0000000000000003
+_mm_cmpestri("is", 2, "This is a string", 16, 0x0) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x0) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x0) = 0000000000000000-000000000000246c
+_mm_cmpistri("is", "This is a string", 0x0) => 2
+_mm_cmpestri("is", "This is a string", 0x0) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x0) = 0000000000000000-000000000000246c
+_mm_cmpestri("is", 2, "This is a string", 16, 0x1) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x1) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x1) = 0000000000000000-000000000000006c
+_mm_cmpistri("is", "This is a string", 0x1) => 2
+_mm_cmpestri("is", "This is a string", 0x1) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x1) = 0000000000000000-000000000000006c
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x0) => 1
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x0) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x0) = 0000000000000000-000000000000c03a
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x0) => 1
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x0) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x0) = 0000000000000000-000000000000c03a
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x1) => 3
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x1) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x1) = 0000000000000000-0000000000000008
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x1) => 3
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x1) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x1) = 0000000000000000-0000000000000008
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x0) => 3
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x0) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x0) = 0000000000000000-0000000000001d48
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x0) => 3
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x0) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x0) = 0000000000000000-0000000000001d48
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x1) => 3
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x1) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x1) = 0000000000000000-0000000000000048
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x1) => 3
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x1) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x1) = 0000000000000000-0000000000000048
+_mm_cmpestri("This is a string", 16, "", 0, 0x0) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x0) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x0) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x0) => 16
+_mm_cmpestri("This is a string", "", 0x0) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x0) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x1) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x1) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x1) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x1) => 8
+_mm_cmpestri("This is a string", "", 0x1) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x1) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x0) => 16
+_mm_cmpestri("", 0, "This is a string", 16, 0x0) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x0) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x0) => 16
+_mm_cmpestri("", "This is a string", 0x0) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x0) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x1) => 8
+_mm_cmpestri("", 0, "This is a string", 16, 0x1) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x1) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x1) => 8
+_mm_cmpestri("", "This is a string", 0x1) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x1) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x4) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x4) => 0
+_mm_cmpestri("This is a string", "This", 0x4) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x4) = 0000000000000000-000000000000000f
+_mm_cmpestri("This is a string", 16, "This", 4, 0x5) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x5) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x5) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x5) => 0
+_mm_cmpestri("This is a string", "This", 0x5) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x5) = 0000000000000000-000000000000000f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x4) = 0000000000000000-000000000000f56f
+_mm_cmpistri("This", "This is a string", 0x4) => 0
+_mm_cmpestri("This", "This is a string", 0x4) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x4) = 0000000000000000-000000000000f56f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x5) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x5) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x5) = 0000000000000000-000000000000006f
+_mm_cmpistri("This", "This is a string", 0x5) => 0
+_mm_cmpestri("This", "This is a string", 0x5) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x5) = 0000000000000000-000000000000006f
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4) => 0
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "is", 2, 0x4) = 0000000000000000-0000000000000003
+_mm_cmpistri("This is a string", "is", 0x4) => 0
+_mm_cmpestri("This is a string", "is", 0x4) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "is", 0x4) = 0000000000000000-0000000000000003
+_mm_cmpestri("This is a string", 16, "is", 2, 0x5) => 0
+_mm_cmpestri("This is a string", 16, "is", 2, 0x5) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "is", 2, 0x5) = 0000000000000000-0000000000000003
+_mm_cmpistri("This is a string", "is", 0x5) => 0
+_mm_cmpestri("This is a string", "is", 0x5) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "is", 0x5) = 0000000000000000-0000000000000003
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x4) = 0000000000000000-000000000000746c
+_mm_cmpistri("is", "This is a string", 0x4) => 2
+_mm_cmpestri("is", "This is a string", 0x4) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x4) = 0000000000000000-000000000000746c
+_mm_cmpestri("is", 2, "This is a string", 16, 0x5) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x5) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x5) = 0000000000000000-000000000000006c
+_mm_cmpistri("is", "This is a string", 0x5) => 2
+_mm_cmpestri("is", "This is a string", 0x5) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x5) = 0000000000000000-000000000000006c
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x4) = 0000000000000000-000000000000ffbf
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x4) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x4) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x4) = 0000000000000000-000000000000ffbf
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x5) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x5) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x5) = 0000000000000000-00000000000000af
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x5) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x5) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x5) = 0000000000000000-00000000000000af
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x4) = 0000000000000000-000000000000f56f
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x4) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x4) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x4) = 0000000000000000-000000000000f56f
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x5) => 1
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x5) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x5) = 0000000000000000-000000000000006e
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x5) => 1
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x5) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x5) = 0000000000000000-000000000000006e
+_mm_cmpestri("This is a string", 16, "", 0, 0x4) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x4) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x4) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x4) => 16
+_mm_cmpestri("This is a string", "", 0x4) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x4) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x5) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x5) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x5) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x5) => 8
+_mm_cmpestri("This is a string", "", 0x5) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x5) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x4) => 16
+_mm_cmpestri("", 0, "This is a string", 16, 0x4) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x4) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x4) => 16
+_mm_cmpestri("", "This is a string", 0x4) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x4) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x5) => 8
+_mm_cmpestri("", 0, "This is a string", 16, 0x5) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x5) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x5) => 8
+_mm_cmpestri("", "This is a string", 0x5) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x5) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x8) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x8) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x8) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x8) => 0
+_mm_cmpestri("This is a string", "This", 0x8) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x8) = 0000000000000000-000000000000000f
+_mm_cmpestri("This is a string", 16, "This", 4, 0x9) => 0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x9) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "This", 4, 0x9) = 0000000000000000-000000000000000f
+_mm_cmpistri("This is a string", "This", 0x9) => 0
+_mm_cmpestri("This is a string", "This", 0x9) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "This", 0x9) = 0000000000000000-000000000000000f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x8) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x8) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x8) = 0000000000000000-000000000000000f
+_mm_cmpistri("This", "This is a string", 0x8) => 0
+_mm_cmpestri("This", "This is a string", 0x8) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x8) = 0000000000000000-000000000000000f
+_mm_cmpestri("This", 4, "This is a string", 16, 0x9) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x9) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x9) = 0000000000000000-000000000000000f
+_mm_cmpistri("This", "This is a string", 0x9) => 0
+_mm_cmpestri("This", "This is a string", 0x9) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x9) = 0000000000000000-000000000000000f
+_mm_cmpestri("This is a string", 16, "is", 2, 0x8) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x8) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x8) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x8) => 16
+_mm_cmpestri("This is a string", "is", 0x8) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x8) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x9) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x9) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x9) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x9) => 8
+_mm_cmpestri("This is a string", "is", 0x9) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x9) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x8) => 16
+_mm_cmpestri("is", 2, "This is a string", 16, 0x8) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x8) = 0000000000000000-0000000000000000
+_mm_cmpistri("is", "This is a string", 0x8) => 16
+_mm_cmpestri("is", "This is a string", 0x8) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("is", "This is a string", 0x8) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x9) => 8
+_mm_cmpestri("is", 2, "This is a string", 16, 0x9) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x9) = 0000000000000000-0000000000000000
+_mm_cmpistri("is", "This is a string", 0x9) => 8
+_mm_cmpestri("is", "This is a string", 0x9) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("is", "This is a string", 0x9) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x8) => 3
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x8) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x8) = 0000000000000000-0000000000000008
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x8) => 3
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x8) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x8) = 0000000000000000-0000000000000008
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x9) => 3
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x9) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x9) = 0000000000000000-0000000000000008
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x9) => 3
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x9) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x9) = 0000000000000000-0000000000000008
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x8) => 3
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x8) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x8) = 0000000000000000-0000000000000008
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x8) => 3
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x8) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x8) = 0000000000000000-0000000000000008
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x9) => 3
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x9) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x9) = 0000000000000000-0000000000000008
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x9) => 3
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x9) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x9) = 0000000000000000-0000000000000008
+_mm_cmpestri("This is a string", 16, "", 0, 0x8) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x8) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x8) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x8) => 16
+_mm_cmpestri("This is a string", "", 0x8) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x8) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x9) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x9) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x9) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x9) => 8
+_mm_cmpestri("This is a string", "", 0x9) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x9) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x8) => 16
+_mm_cmpestri("", 0, "This is a string", 16, 0x8) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x8) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x8) => 16
+_mm_cmpestri("", "This is a string", 0x8) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x8) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x9) => 8
+_mm_cmpestri("", 0, "This is a string", 16, 0x9) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", 0, "This is a string", 16, 0x9) = 0000000000000000-0000000000000000
+_mm_cmpistri("", "This is a string", 0x9) => 8
+_mm_cmpestri("", "This is a string", 0x9) flags: a:1 s:1 z:0 c:0 o:0
+mm_cmpestrm("", "This is a string", 0x9) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0xc) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0xc) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0xc) => 16
+_mm_cmpestri("This is a string", "This", 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0xc) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0xd) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0xd) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0xd) => 8
+_mm_cmpestri("This is a string", "This", 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0xd) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0xc) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0xc) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0xc) = 0000000000000000-0000000000000001
+_mm_cmpistri("This", "This is a string", 0xc) => 0
+_mm_cmpestri("This", "This is a string", 0xc) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0xc) = 0000000000000000-0000000000000001
+_mm_cmpestri("This", 4, "This is a string", 16, 0xd) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0xd) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0xd) = 0000000000000000-0000000000000001
+_mm_cmpistri("This", "This is a string", 0xd) => 0
+_mm_cmpestri("This", "This is a string", 0xd) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0xd) = 0000000000000000-0000000000000001
+_mm_cmpestri("This is a string", 16, "is", 2, 0xc) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0xc) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0xc) => 16
+_mm_cmpestri("This is a string", "is", 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0xc) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0xd) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0xd) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0xd) => 8
+_mm_cmpestri("This is a string", "is", 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0xd) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0xc) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0xc) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0xc) = 0000000000000000-0000000000000024
+_mm_cmpistri("is", "This is a string", 0xc) => 2
+_mm_cmpestri("is", "This is a string", 0xc) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0xc) = 0000000000000000-0000000000000024
+_mm_cmpestri("is", 2, "This is a string", 16, 0xd) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0xd) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0xd) = 0000000000000000-0000000000000024
+_mm_cmpistri("is", "This is a string", 0xd) => 2
+_mm_cmpestri("is", "This is a string", 0xd) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0xd) = 0000000000000000-0000000000000024
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0xc) => 16
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0xc) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0xc) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0xc) => 16
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0xc) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0xc) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0xd) => 8
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0xd) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0xd) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0xd) => 8
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0xd) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0xd) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0xc) => 16
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0xc) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0xc) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0xc) => 16
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0xc) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0xc) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0xd) => 8
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0xd) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0xd) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0xd) => 8
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0xd) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0xd) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0xc) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0xc) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0xc) => 16
+_mm_cmpestri("This is a string", "", 0xc) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0xc) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0xd) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0xd) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0xd) => 8
+_mm_cmpestri("This is a string", "", 0xd) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0xd) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0xc) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0xc) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0xc) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0xc) => 0
+_mm_cmpestri("", "This is a string", 0xc) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0xc) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0xd) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0xd) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0xd) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0xd) => 0
+_mm_cmpestri("", "This is a string", 0xd) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0xd) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x10) => 4
+_mm_cmpestri("This is a string", 16, "This", 4, 0x10) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x10) = 0000000000000000-000000000000fff0
+_mm_cmpistri("This is a string", "This", 0x10) => 4
+_mm_cmpestri("This is a string", "This", 0x10) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", "This", 0x10) = 0000000000000000-000000000000fff0
+_mm_cmpestri("This is a string", 16, "This", 4, 0x11) => 4
+_mm_cmpestri("This is a string", 16, "This", 4, 0x11) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x11) = 0000000000000000-00000000000000f0
+_mm_cmpistri("This is a string", "This", 0x11) => 4
+_mm_cmpestri("This is a string", "This", 0x11) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", "This", 0x11) = 0000000000000000-00000000000000f0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x10) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x10) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x10) = 0000000000000000-000000000000db90
+_mm_cmpistri("This", "This is a string", 0x10) => 4
+_mm_cmpestri("This", "This is a string", 0x10) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x10) = 0000000000000000-000000000000db90
+_mm_cmpestri("This", 4, "This is a string", 16, 0x11) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x11) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x11) = 0000000000000000-0000000000000090
+_mm_cmpistri("This", "This is a string", 0x11) => 4
+_mm_cmpestri("This", "This is a string", 0x11) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x11) = 0000000000000000-0000000000000090
+_mm_cmpestri("This is a string", 16, "is", 2, 0x10) => 2
+_mm_cmpestri("This is a string", 16, "is", 2, 0x10) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x10) = 0000000000000000-000000000000fffc
+_mm_cmpistri("This is a string", "is", 0x10) => 2
+_mm_cmpestri("This is a string", "is", 0x10) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", "is", 0x10) = 0000000000000000-000000000000fffc
+_mm_cmpestri("This is a string", 16, "is", 2, 0x11) => 2
+_mm_cmpestri("This is a string", 16, "is", 2, 0x11) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x11) = 0000000000000000-00000000000000fc
+_mm_cmpistri("This is a string", "is", 0x11) => 2
+_mm_cmpestri("This is a string", "is", 0x11) flags: a:0 s:0 z:1 c:1 o:0
+mm_cmpestrm("This is a string", "is", 0x11) = 0000000000000000-00000000000000fc
+_mm_cmpestri("is", 2, "This is a string", 16, 0x10) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x10) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x10) = 0000000000000000-000000000000db93
+_mm_cmpistri("is", "This is a string", 0x10) => 0
+_mm_cmpestri("is", "This is a string", 0x10) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x10) = 0000000000000000-000000000000db93
+_mm_cmpestri("is", 2, "This is a string", 16, 0x11) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x11) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x11) = 0000000000000000-0000000000000093
+_mm_cmpistri("is", "This is a string", 0x11) => 0
+_mm_cmpestri("is", "This is a string", 0x11) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x11) = 0000000000000000-0000000000000093
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x10) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x10) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x10) = 0000000000000000-0000000000003fc5
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x10) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x10) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x10) = 0000000000000000-0000000000003fc5
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x11) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x11) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x11) = 0000000000000000-00000000000000f7
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x11) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x11) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x11) = 0000000000000000-00000000000000f7
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x10) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x10) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x10) = 0000000000000000-000000000000e2b7
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x10) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x10) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x10) = 0000000000000000-000000000000e2b7
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x11) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x11) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x11) = 0000000000000000-00000000000000b7
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x11) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x11) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x11) = 0000000000000000-00000000000000b7
+_mm_cmpestri("This is a string", 16, "", 0, 0x10) => 0
+_mm_cmpestri("This is a string", 16, "", 0, 0x10) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "", 0, 0x10) = 0000000000000000-000000000000ffff
+_mm_cmpistri("This is a string", "", 0x10) => 0
+_mm_cmpestri("This is a string", "", 0x10) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "", 0x10) = 0000000000000000-000000000000ffff
+_mm_cmpestri("This is a string", 16, "", 0, 0x11) => 0
+_mm_cmpestri("This is a string", 16, "", 0, 0x11) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", 16, "", 0, 0x11) = 0000000000000000-00000000000000ff
+_mm_cmpistri("This is a string", "", 0x11) => 0
+_mm_cmpestri("This is a string", "", 0x11) flags: a:0 s:0 z:1 c:1 o:1
+mm_cmpestrm("This is a string", "", 0x11) = 0000000000000000-00000000000000ff
+_mm_cmpestri("", 0, "This is a string", 16, 0x10) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x10) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x10) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0x10) => 0
+_mm_cmpestri("", "This is a string", 0x10) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x10) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x11) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x11) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x11) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0x11) => 0
+_mm_cmpestri("", "This is a string", 0x11) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x11) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x30) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x30) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x30) => 16
+_mm_cmpestri("This is a string", "This", 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x30) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x31) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x31) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x31) => 8
+_mm_cmpestri("This is a string", "This", 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x31) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x30) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x30) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x30) = 0000000000000000-000000000000db90
+_mm_cmpistri("This", "This is a string", 0x30) => 4
+_mm_cmpestri("This", "This is a string", 0x30) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x30) = 0000000000000000-000000000000db90
+_mm_cmpestri("This", 4, "This is a string", 16, 0x31) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x31) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x31) = 0000000000000000-0000000000000090
+_mm_cmpistri("This", "This is a string", 0x31) => 4
+_mm_cmpestri("This", "This is a string", 0x31) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x31) = 0000000000000000-0000000000000090
+_mm_cmpestri("This is a string", 16, "is", 2, 0x30) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x30) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x30) => 16
+_mm_cmpestri("This is a string", "is", 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x30) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x31) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x31) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x31) => 8
+_mm_cmpestri("This is a string", "is", 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x31) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x30) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x30) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x30) = 0000000000000000-000000000000db93
+_mm_cmpistri("is", "This is a string", 0x30) => 0
+_mm_cmpestri("is", "This is a string", 0x30) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x30) = 0000000000000000-000000000000db93
+_mm_cmpestri("is", 2, "This is a string", 16, 0x31) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x31) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x31) = 0000000000000000-0000000000000093
+_mm_cmpistri("is", "This is a string", 0x31) => 0
+_mm_cmpestri("is", "This is a string", 0x31) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x31) = 0000000000000000-0000000000000093
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x30) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x30) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x30) = 0000000000000000-0000000000003fc5
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x30) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x30) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x30) = 0000000000000000-0000000000003fc5
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x31) => 0
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x31) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x31) = 0000000000000000-00000000000000f7
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x31) => 0
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x31) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x31) = 0000000000000000-00000000000000f7
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x30) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x30) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x30) = 0000000000000000-000000000000e2b7
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x30) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x30) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x30) = 0000000000000000-000000000000e2b7
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x31) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x31) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x31) = 0000000000000000-00000000000000b7
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x31) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x31) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x31) = 0000000000000000-00000000000000b7
+_mm_cmpestri("This is a string", 16, "", 0, 0x30) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x30) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x30) => 16
+_mm_cmpestri("This is a string", "", 0x30) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x30) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x31) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x31) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x31) => 8
+_mm_cmpestri("This is a string", "", 0x31) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x31) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x30) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x30) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x30) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0x30) => 0
+_mm_cmpestri("", "This is a string", 0x30) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x30) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x31) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x31) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x31) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0x31) => 0
+_mm_cmpestri("", "This is a string", 0x31) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x31) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4c) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x4c) => 16
+_mm_cmpestri("This is a string", "This", 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4d) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x4d) => 8
+_mm_cmpestri("This is a string", "This", 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4c) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x4c) = 0000000000000000-00000000000000ff
+_mm_cmpistri("This", "This is a string", 0x4c) => 0
+_mm_cmpestri("This", "This is a string", 0x4c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x4c) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4d) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x4d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x4d) = 0000000000000000-000000000000ffff
+_mm_cmpistri("This", "This is a string", 0x4d) => 0
+_mm_cmpestri("This", "This is a string", 0x4d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x4d) = 0000000000000000-000000000000ffff
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4c) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x4c) => 16
+_mm_cmpestri("This is a string", "is", 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4d) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x4d) => 8
+_mm_cmpestri("This is a string", "is", 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4c) => 5
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4c) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x4c) = 0000000000000000-0000000000ff0000
+_mm_cmpistri("is", "This is a string", 0x4c) => 5
+_mm_cmpestri("is", "This is a string", 0x4c) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x4c) = 0000000000000000-0000000000ff0000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4d) => 5
+_mm_cmpestri("is", 2, "This is a string", 16, 0x4d) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x4d) = 00000000ffff0000-0000000000000000
+_mm_cmpistri("is", "This is a string", 0x4d) => 5
+_mm_cmpestri("is", "This is a string", 0x4d) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x4d) = 00000000ffff0000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4c) => 16
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x4c) => 16
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x4c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4d) => 8
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x4d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x4d) => 8
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x4d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4c) => 16
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x4c) => 16
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x4c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4d) => 8
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x4d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x4d) => 8
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x4d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x4c) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x4c) => 16
+_mm_cmpestri("This is a string", "", 0x4c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x4c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x4d) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x4d) => 8
+_mm_cmpestri("This is a string", "", 0x4d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x4d) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x4c) => 15
+_mm_cmpestri("", 0, "This is a string", 16, 0x4c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x4c) = 00000000ffffffff-00000000ffffffff
+_mm_cmpistri("", "This is a string", 0x4c) => 15
+_mm_cmpestri("", "This is a string", 0x4c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x4c) = 00000000ffffffff-00000000ffffffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x4d) => 7
+_mm_cmpestri("", 0, "This is a string", 16, 0x4d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x4d) = 00000000ffffffff-00000000ffffffff
+_mm_cmpistri("", "This is a string", 0x4d) => 7
+_mm_cmpestri("", "This is a string", 0x4d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x4d) = 00000000ffffffff-00000000ffffffff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x2c) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x2c) => 16
+_mm_cmpestri("This is a string", "This", 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x2d) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x2d) => 8
+_mm_cmpestri("This is a string", "This", 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x2c) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x2c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x2c) = 0000000000000000-0000000000000001
+_mm_cmpistri("This", "This is a string", 0x2c) => 0
+_mm_cmpestri("This", "This is a string", 0x2c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x2c) = 0000000000000000-0000000000000001
+_mm_cmpestri("This", 4, "This is a string", 16, 0x2d) => 0
+_mm_cmpestri("This", 4, "This is a string", 16, 0x2d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", 4, "This is a string", 16, 0x2d) = 0000000000000000-0000000000000001
+_mm_cmpistri("This", "This is a string", 0x2d) => 0
+_mm_cmpestri("This", "This is a string", 0x2d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("This", "This is a string", 0x2d) = 0000000000000000-0000000000000001
+_mm_cmpestri("This is a string", 16, "is", 2, 0x2c) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x2c) => 16
+_mm_cmpestri("This is a string", "is", 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x2d) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x2d) => 8
+_mm_cmpestri("This is a string", "is", 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x2c) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x2c) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x2c) = 0000000000000000-0000000000000024
+_mm_cmpistri("is", "This is a string", 0x2c) => 2
+_mm_cmpestri("is", "This is a string", 0x2c) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x2c) = 0000000000000000-0000000000000024
+_mm_cmpestri("is", 2, "This is a string", 16, 0x2d) => 2
+_mm_cmpestri("is", 2, "This is a string", 16, 0x2d) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", 2, "This is a string", 16, 0x2d) = 0000000000000000-0000000000000024
+_mm_cmpistri("is", "This is a string", 0x2d) => 2
+_mm_cmpestri("is", "This is a string", 0x2d) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("is", "This is a string", 0x2d) = 0000000000000000-0000000000000024
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x2c) => 16
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x2c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x2c) => 16
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x2c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x2d) => 8
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x2d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x2d) => 8
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x2d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x2c) => 16
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x2c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x2c) => 16
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x2c) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x2d) => 8
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x2d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x2d) => 8
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x2d) flags: a:1 s:0 z:0 c:0 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x2c) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x2c) => 16
+_mm_cmpestri("This is a string", "", 0x2c) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x2c) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x2d) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x2d) => 8
+_mm_cmpestri("This is a string", "", 0x2d) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x2d) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x2c) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x2c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x2c) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0x2c) => 0
+_mm_cmpestri("", "This is a string", 0x2c) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x2c) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x2d) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x2d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x2d) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0x2d) => 0
+_mm_cmpestri("", "This is a string", 0x2d) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x2d) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x34) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x34) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x34) => 16
+_mm_cmpestri("This is a string", "This", 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x34) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x35) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x35) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x35) => 8
+_mm_cmpestri("This is a string", "This", 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x35) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x34) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x34) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x34) = 0000000000000000-0000000000000a90
+_mm_cmpistri("This", "This is a string", 0x34) => 4
+_mm_cmpestri("This", "This is a string", 0x34) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x34) = 0000000000000000-0000000000000a90
+_mm_cmpestri("This", 4, "This is a string", 16, 0x35) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x35) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x35) = 0000000000000000-0000000000000090
+_mm_cmpistri("This", "This is a string", 0x35) => 4
+_mm_cmpestri("This", "This is a string", 0x35) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x35) = 0000000000000000-0000000000000090
+_mm_cmpestri("This is a string", 16, "is", 2, 0x34) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x34) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x34) => 16
+_mm_cmpestri("This is a string", "is", 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x34) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x35) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x35) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x35) => 8
+_mm_cmpestri("This is a string", "is", 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x35) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x34) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x34) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x34) = 0000000000000000-0000000000008b93
+_mm_cmpistri("is", "This is a string", 0x34) => 0
+_mm_cmpestri("is", "This is a string", 0x34) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x34) = 0000000000000000-0000000000008b93
+_mm_cmpestri("is", 2, "This is a string", 16, 0x35) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x35) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x35) = 0000000000000000-0000000000000093
+_mm_cmpistri("is", "This is a string", 0x35) => 0
+_mm_cmpestri("is", "This is a string", 0x35) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x35) = 0000000000000000-0000000000000093
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x34) => 6
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x34) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x34) = 0000000000000000-0000000000000040
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x34) => 6
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x34) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x34) = 0000000000000000-0000000000000040
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x35) => 4
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x35) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x35) = 0000000000000000-0000000000000050
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x35) => 4
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x35) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x35) = 0000000000000000-0000000000000050
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x34) => 4
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x34) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x34) = 0000000000000000-0000000000000a90
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x34) => 4
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x34) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x34) = 0000000000000000-0000000000000a90
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x35) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x35) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x35) = 0000000000000000-0000000000000091
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x35) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x35) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x35) = 0000000000000000-0000000000000091
+_mm_cmpestri("This is a string", 16, "", 0, 0x34) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x34) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x34) => 16
+_mm_cmpestri("This is a string", "", 0x34) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x34) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x35) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x35) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x35) => 8
+_mm_cmpestri("This is a string", "", 0x35) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x35) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x34) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x34) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x34) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0x34) => 0
+_mm_cmpestri("", "This is a string", 0x34) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x34) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x35) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x35) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x35) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0x35) => 0
+_mm_cmpestri("", "This is a string", 0x35) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x35) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x36) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x36) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x36) => 16
+_mm_cmpestri("This is a string", "This", 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x36) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x37) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x37) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x37) => 8
+_mm_cmpestri("This is a string", "This", 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x37) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x36) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x36) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x36) = 0000000000000000-0000000000000a90
+_mm_cmpistri("This", "This is a string", 0x36) => 4
+_mm_cmpestri("This", "This is a string", 0x36) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x36) = 0000000000000000-0000000000000a90
+_mm_cmpestri("This", 4, "This is a string", 16, 0x37) => 4
+_mm_cmpestri("This", 4, "This is a string", 16, 0x37) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x37) = 0000000000000000-0000000000000090
+_mm_cmpistri("This", "This is a string", 0x37) => 4
+_mm_cmpestri("This", "This is a string", 0x37) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x37) = 0000000000000000-0000000000000090
+_mm_cmpestri("This is a string", 16, "is", 2, 0x36) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x36) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x36) => 16
+_mm_cmpestri("This is a string", "is", 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x36) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x37) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x37) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x37) => 8
+_mm_cmpestri("This is a string", "is", 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x37) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x36) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x36) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x36) = 0000000000000000-0000000000008b93
+_mm_cmpistri("is", "This is a string", 0x36) => 0
+_mm_cmpestri("is", "This is a string", 0x36) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x36) = 0000000000000000-0000000000008b93
+_mm_cmpestri("is", 2, "This is a string", 16, 0x37) => 0
+_mm_cmpestri("is", 2, "This is a string", 16, 0x37) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x37) = 0000000000000000-0000000000000093
+_mm_cmpistri("is", "This is a string", 0x37) => 0
+_mm_cmpestri("is", "This is a string", 0x37) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x37) = 0000000000000000-0000000000000093
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x36) => 6
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x36) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x36) = 0000000000000000-0000000000000040
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x36) => 6
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x36) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x36) = 0000000000000000-0000000000000040
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x37) => 4
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x37) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x37) = 0000000000000000-0000000000000050
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x37) => 4
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x37) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x37) = 0000000000000000-0000000000000050
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x36) => 4
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x36) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x36) = 0000000000000000-0000000000000a90
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x36) => 4
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x36) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x36) = 0000000000000000-0000000000000a90
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x37) => 0
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x37) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x37) = 0000000000000000-0000000000000091
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x37) => 0
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x37) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x37) = 0000000000000000-0000000000000091
+_mm_cmpestri("This is a string", 16, "", 0, 0x36) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x36) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x36) => 16
+_mm_cmpestri("This is a string", "", 0x36) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x36) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x37) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x37) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x37) => 8
+_mm_cmpestri("This is a string", "", 0x37) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x37) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x36) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x36) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x36) = 0000000000000000-000000000000ffff
+_mm_cmpistri("", "This is a string", 0x36) => 0
+_mm_cmpestri("", "This is a string", 0x36) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x36) = 0000000000000000-000000000000ffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x37) => 0
+_mm_cmpestri("", 0, "This is a string", 16, 0x37) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x37) = 0000000000000000-00000000000000ff
+_mm_cmpistri("", "This is a string", 0x37) => 0
+_mm_cmpestri("", "This is a string", 0x37) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x37) = 0000000000000000-00000000000000ff
+_mm_cmpestri("This is a string", 16, "This", 4, 0x74) => 16
+_mm_cmpestri("This is a string", 16, "This", 4, 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x74) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x74) => 16
+_mm_cmpestri("This is a string", "This", 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x74) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "This", 4, 0x75) => 8
+_mm_cmpestri("This is a string", 16, "This", 4, 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "This", 4, 0x75) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "This", 0x75) => 8
+_mm_cmpestri("This is a string", "This", 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "This", 0x75) = 0000000000000000-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x74) => 11
+_mm_cmpestri("This", 4, "This is a string", 16, 0x74) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x74) = 00000000ff00ff00-0000000000000000
+_mm_cmpistri("This", "This is a string", 0x74) => 11
+_mm_cmpestri("This", "This is a string", 0x74) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x74) = 00000000ff00ff00-0000000000000000
+_mm_cmpestri("This", 4, "This is a string", 16, 0x75) => 7
+_mm_cmpestri("This", 4, "This is a string", 16, 0x75) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", 4, "This is a string", 16, 0x75) = 000000000000ffff-0000000000000000
+_mm_cmpistri("This", "This is a string", 0x75) => 7
+_mm_cmpestri("This", "This is a string", 0x75) flags: a:0 s:1 z:0 c:1 o:0
+mm_cmpestrm("This", "This is a string", 0x75) = 000000000000ffff-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x74) => 16
+_mm_cmpestri("This is a string", 16, "is", 2, 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x74) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x74) => 16
+_mm_cmpestri("This is a string", "is", 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x74) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "is", 2, 0x75) => 8
+_mm_cmpestri("This is a string", 16, "is", 2, 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "is", 2, 0x75) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "is", 0x75) => 8
+_mm_cmpestri("This is a string", "is", 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "is", 0x75) = 0000000000000000-0000000000000000
+_mm_cmpestri("is", 2, "This is a string", 16, 0x74) => 15
+_mm_cmpestri("is", 2, "This is a string", 16, 0x74) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x74) = 00000000ff00ffff-000000000000ffff
+_mm_cmpistri("is", "This is a string", 0x74) => 15
+_mm_cmpestri("is", "This is a string", 0x74) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x74) = 00000000ff00ffff-000000000000ffff
+_mm_cmpestri("is", 2, "This is a string", 16, 0x75) => 7
+_mm_cmpestri("is", 2, "This is a string", 16, 0x75) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", 2, "This is a string", 16, 0x75) = 000000000000ffff-00000000ffffffff
+_mm_cmpistri("is", "This is a string", 0x75) => 7
+_mm_cmpestri("is", "This is a string", 0x75) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("is", "This is a string", 0x75) = 000000000000ffff-00000000ffffffff
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x74) => 6
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x74) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x74) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x74) => 6
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x74) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x74) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x75) => 6
+_mm_cmpestri("This is a string", 16, "maestrum-foo-bar", 16, 0x75) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", 16, "maestrum-foo-bar", 16, 0x75) = 000000000000ffff-0000000000000000
+_mm_cmpistri("This is a string", "maestrum-foo-bar", 0x75) => 6
+_mm_cmpestri("This is a string", "maestrum-foo-bar", 0x75) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("This is a string", "maestrum-foo-bar", 0x75) = 000000000000ffff-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x74) => 11
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x74) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x74) = 00000000ff00ff00-0000000000000000
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x74) => 11
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x74) flags: a:0 s:0 z:0 c:1 o:0
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x74) = 00000000ff00ff00-0000000000000000
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x75) => 7
+_mm_cmpestri("maestrum-foo-bar", 16, "This is a string", 16, 0x75) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", 16, "This is a string", 16, 0x75) = 000000000000ffff-000000000000ffff
+_mm_cmpistri("maestrum-foo-bar", "This is a string", 0x75) => 7
+_mm_cmpestri("maestrum-foo-bar", "This is a string", 0x75) flags: a:0 s:0 z:0 c:1 o:1
+mm_cmpestrm("maestrum-foo-bar", "This is a string", 0x75) = 000000000000ffff-000000000000ffff
+_mm_cmpestri("This is a string", 16, "", 0, 0x74) => 16
+_mm_cmpestri("This is a string", 16, "", 0, 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x74) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x74) => 16
+_mm_cmpestri("This is a string", "", 0x74) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x74) = 0000000000000000-0000000000000000
+_mm_cmpestri("This is a string", 16, "", 0, 0x75) => 8
+_mm_cmpestri("This is a string", 16, "", 0, 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", 16, "", 0, 0x75) = 0000000000000000-0000000000000000
+_mm_cmpistri("This is a string", "", 0x75) => 8
+_mm_cmpestri("This is a string", "", 0x75) flags: a:0 s:0 z:1 c:0 o:0
+mm_cmpestrm("This is a string", "", 0x75) = 0000000000000000-0000000000000000
+_mm_cmpestri("", 0, "This is a string", 16, 0x74) => 15
+_mm_cmpestri("", 0, "This is a string", 16, 0x74) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x74) = 00000000ffffffff-00000000ffffffff
+_mm_cmpistri("", "This is a string", 0x74) => 15
+_mm_cmpestri("", "This is a string", 0x74) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x74) = 00000000ffffffff-00000000ffffffff
+_mm_cmpestri("", 0, "This is a string", 16, 0x75) => 7
+_mm_cmpestri("", 0, "This is a string", 16, 0x75) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", 0, "This is a string", 16, 0x75) = 00000000ffffffff-00000000ffffffff
+_mm_cmpistri("", "This is a string", 0x75) => 7
+_mm_cmpestri("", "This is a string", 0x75) flags: a:0 s:1 z:0 c:1 o:1
+mm_cmpestrm("", "This is a string", 0x75) = 00000000ffffffff-00000000ffffffff
+crc32(0x0, byte:0x0) => 0x0
+crc32(0x0, byte:0xa) => 0x6be22838
+crc32(0x6be22838, dword:0x0) => 0xb545d4c9
+crc32(0xb545d4c9, dword:0x123456) => 0xc4dd37b5
+crc32(0xc4dd37b5, word:0x8765) => 0x89047b68
+crc32(0x89047b68, qword:0x34567890) => 0x68d0e9ae
diff --git a/tests/ref28.txt b/tests/ref28.txt
new file mode 100644
index 0000000..033d0f4
--- /dev/null
+++ b/tests/ref28.txt
@@ -0,0 +1,31 @@
+test SHA Ext
+sha1rnds4(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001, 0x0) => f40757f7-b4b82290-eab46b51-56a09e67
+sha1rnds4(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001, 0x1) => 9477347e-209fe171-5285d814-5bb67ae9
+sha1rnds4(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001, 0x2) => e27962a9-e186daec-1ca4d63c-23c6ef38
+sha1rnds4(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001, 0x3) => f32a4da8-6c2529f4-85aebf4c-b298b076
+sha1rnds4(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000, 0x0) => 986d7873-b5db5395-2ab46b29-16a09e66
+sha1rnds4(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000, 0x1) => 78dd5f0b-21c31271-9285d7eb-1bb67ae8
+sha1rnds4(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000, 0x2) => c6df831c-e2aa0bf1-5ca4d613-e3c6ef36
+sha1rnds4(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000, 0x3) => 57906d5d-6d485af4-c5aebf23-7298b075
+sha1rnds4(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000, 0x0) => d8ae9505-35dd5bf7-eab46f39-96a09e86
+sha1rnds4(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000, 0x1) => f91d79e9-61c513cc-4285dbed-1bb67b08
+sha1rnds4(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000, 0x2) => 4721274f-62ac1813-9ca4da2b-a3c6ef57
+sha1rnds4(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000, 0x3) => 57d20b8d-ad4a5c6d-b5aec325-7298b095
+sha1msg1(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001) => 00000000-00000000-00000004-00000003
+sha1msg1(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => 00000000-00000000-ffffffff-00000000
+sha1msg1(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 00000006-00000002-fffffffd-00000001
+sha1msg2(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001) => 00000006-00000004-00000002-0000000c
+sha1msg2(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => 00000000-02468ace-00000001-00000000
+sha1msg2(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 00000008-02468ac8-00000005-00000012
+sha1nexte(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001) => 00000004-00000003-00000002-00000001
+sha1nexte(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => ffffffff-00000000-01234567-80000000
+sha1nexte(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 00000000-00000000-01234567-80000000
+sha256msg1(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001) => 02004000-00000000-00000000-00000000
+sha256msg1(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => 11002000-00000000-00000000-00000000
+sha256msg1(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 11002004-08010003-0600c002-04008001
+sha256msg2(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001) => 100000a1-cc000078-00028000-0001e000
+sha256msg2(00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => 00006fe7-00000000-003fffff-00000000
+sha256msg2(00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 0000b02c-0000a003-00400001-00000001
+sha256rnds2(00000000-00000000-00000000-00000000 ,00000004-00000003-00000002-00000001 ,ffffffff-00000000-01234567-80000000) => 6da40f0a-88601101-0353cda8-88400100
+sha256rnds2(00000004-00000003-00000002-00000001 ,00000000-00000000-00000000-00000000 ,ffffffff-00000000-01234567-80000000) => fc0f56a9-80000003-1bf348ad-80000006
+sha256rnds2(ffffffff-00000000-01234567-80000000 ,00000004-00000003-00000002-00000001 ,00000000-00000000-00000000-00000000) => c8b008c8-8983566d-ec5ad91b-89634665
diff --git a/tests/ref29.txt b/tests/ref29.txt
new file mode 100644
index 0000000..6b25f7d
--- /dev/null
+++ b/tests/ref29.txt
@@ -0,0 +1,2 @@
+Lock XADD: Res = 0x456, Ed = 0x579
+Lock XCHG: Res = 0x579, Ed = 0x123
diff --git a/tests/test17.c b/tests/test17.c
index 632d13c..8b0cfc4 100644
--- a/tests/test17.c
+++ b/tests/test17.c
@@ -601,6 +601,11 @@ printf(N " %g, %g => %g\n", b, a, *(float*)&r);
MULTIGO2sd(div, divsd)
MULTIGO2sd(max, maxsd)
MULTIGO1ps2dq(cvtps, cvtps2pd)
+ MULITGO2Cps(dp, dpps, 0xff)
+ MULITGO2Cps(dp, dpps, 0x3f)
+ MULITGO2Cps(dp, dpps, 0xf3)
+ MULITGO2Cps(dp, dpps, 0x53)
return 0;
}
+
diff --git a/tests/test23 b/tests/test23
new file mode 100755
index 0000000..e6e8463
--- /dev/null
+++ b/tests/test23
Binary files differ
diff --git a/tests/test23.c b/tests/test23.c
new file mode 100644
index 0000000..7328a39
--- /dev/null
+++ b/tests/test23.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdint.h>
+// Build with `gcc -march=core2 -O2 test23.c -o test23`
+
+uint64_t pshufb(uint64_t Gm, uint64_t Em) {
+uint64_t Res;
+asm(
+"movq %[_Gm], %%mm0\n"
+"movq %[_Em], %%mm1\n"
+"pshufb %%mm1, %%mm0\n"
+"movq %%mm0, %[_Res]\n"
+: [_Res] "+r"(Res)
+: [_Gm] "r"(Gm)
+, [_Em] "r"(Em)
+);
+return Res;
+}
+
+int main() {
+uint64_t Gm = 0x12345678abcdef00;
+uint64_t Em = 0x8182888971727879;
+uint64_t Res = pshufb(Gm, Em);
+printf("Res = 0x%lx\n", Res);
+//assert(Res == 0xefcd00ef);
+return 0;
+}
diff --git a/tests/test24 b/tests/test24
new file mode 100755
index 0000000..3096380
--- /dev/null
+++ b/tests/test24
Binary files differ
diff --git a/tests/test24.c b/tests/test24.c
new file mode 100644
index 0000000..cd07e13
--- /dev/null
+++ b/tests/test24.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdint.h>
+// Build with `gcc -march=core2 -O2 test24.c -o test24`
+
+
+uint64_t a = 0x12345678abcdefed;
+uint32_t b = 0x12345678;
+uint16_t c = 0x1234;
+
+int main()
+{
+ uint64_t ret1;
+ uint32_t ret2;
+ uint16_t ret3;
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=r"(ret1)
+ : "m"(a)
+ : "memory");
+ printf("ret = 0x%lx\n", ret1);
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=r"(ret2)
+ : "m"(b)
+ : "memory");
+ printf("ret = 0x%x\n", ret2);
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=r"(ret3)
+ : "m"(c)
+ : "memory");
+ printf("ret = 0x%x\n", ret3);
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=m"(ret1)
+ : "r"(a)
+ : "memory");
+ printf("ret = 0x%lx\n", ret1);
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=m"(ret2)
+ : "r"(b)
+ : "memory");
+ printf("ret = 0x%x\n", ret2);
+
+ asm volatile(
+ "movbe %1, %0\n"
+ : "=m"(ret3)
+ : "r"(c)
+ : "memory");
+ printf("ret = 0x%x\n", ret3);
+
+ asm volatile(
+ "bswap %0\n"
+ : "+r"(ret1)
+ :
+ :);
+ printf("ret = 0x%lx\n", ret1);
+
+ asm volatile(
+ "bswap %0\n"
+ : "+r"(ret2)
+ :
+ :);
+ printf("ret = 0x%x\n", ret2);
+ return 0;
+}
diff --git a/tests/test25 b/tests/test25
new file mode 100755
index 0000000..2d65ead
--- /dev/null
+++ b/tests/test25
Binary files differ
diff --git a/tests/test25.c b/tests/test25.c
new file mode 100644
index 0000000..6f0be71
--- /dev/null
+++ b/tests/test25.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+// Build with `gcc -march=core2 -O2 test25.c -o test25`
+
+asm(
+"foo: \n\t"
+ "flds 0(%rdi) \n\t"
+ "flds 4(%rdi) \n\t"
+ "flds 8(%rdi) \n\t"
+ "flds 12(%rdi) \n\t"
+ "flds 16(%rdi) \n\t"
+ "flds 20(%rdi) \n\t"
+ "flds 24(%rdi) \n\t"
+ "flds 28(%rdi) \n\t"
+ "cmp $0, %rdi \n\t"
+ "je 1f \n\t"
+ "jne 1f \n\t"
+ "flds 32(%rdi) \n\t"
+ "flds 36(%rdi) \n\t"
+"1: \n\t"
+ "fstps 0(%rsi) \n\t"
+ "fstps 4(%rsi) \n\t"
+ "fstps 8(%rsi) \n\t"
+ "fstps 12(%rsi) \n\t"
+ "fstps 16(%rsi) \n\t"
+ "fstps 20(%rsi) \n\t"
+ "fstps 24(%rsi) \n\t"
+ "fstps 28(%rsi) \n\t"
+ "je 1f \n\t"
+ "jne 1f \n\t"
+ "fstps 32(%rdi) \n\t"
+ "fstps 36(%rdi) \n\t"
+"1: \n\t"
+ "ret \n\t"
+);
+
+extern void foo(float* src, float* dst);
+
+int main(void)
+{
+ float src[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ float dst[10] = { 0 };
+ foo(src, dst);
+ for (int i = 0; i < 10; ++i) {
+ printf("%f\n", dst[i]);
+ }
+ return 0;
+}
diff --git a/tests/test26 b/tests/test26
new file mode 100755
index 0000000..a6fb3ea
--- /dev/null
+++ b/tests/test26
Binary files differ
diff --git a/tests/test26.c b/tests/test26.c
new file mode 100644
index 0000000..64f1b45
--- /dev/null
+++ b/tests/test26.c
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <fenv.h>
+#include <math.h>
+// Build with `gcc -march=core2 -O0 test26.c -o test26 -lm`
+
+#define TEST(fn, val) \
+ printf("Testing %s(%f)\n", #fn, val); \
+ fesetround(FE_UPWARD); \
+ printf("FE_UPWARD: %.1f\n", (double)fn(val)); \
+ printf("Current rounding mode: 0x%x\n", fegetround()); \
+ fesetround(FE_DOWNWARD); \
+ printf("FE_DOWNWARD: %.1f\n", (double)fn(val)); \
+ printf("Current rounding mode: 0x%x\n", fegetround()); \
+ fesetround(FE_TOWARDZERO); \
+ printf("FE_TOWARDZERO: %.1f\n", (double)fn(val)); \
+ printf("Current rounding mode: 0x%x\n", fegetround()); \
+ fesetround(FE_TONEAREST); \
+ printf("FE_TONEAREST: %.1f\n", (double)fn(val)); \
+ printf("Current rounding mode: 0x%x\n\n", fegetround());
+
+int main()
+{
+ TEST(rint, 1.0f);
+ TEST(rint, 1.3f);
+ TEST(rint, 1.5f);
+ TEST(rint, 1.8f);
+
+ TEST(rint, 2.0f);
+ TEST(rint, 2.3f);
+ TEST(rint, 2.5f);
+ TEST(rint, 2.8f);
+
+ TEST(rintf, 1.0f);
+ TEST(rintf, 1.3f);
+ TEST(rintf, 1.5f);
+ TEST(rintf, 1.8f);
+
+ TEST(rintf, 2.0f);
+ TEST(rintf, 2.3f);
+ TEST(rintf, 2.5f);
+ TEST(rintf, 2.8f);
+
+ TEST(nearbyint, 1.0f);
+ TEST(nearbyint, 1.3f);
+ TEST(nearbyint, 1.5f);
+ TEST(nearbyint, 1.8f);
+
+ TEST(nearbyint, 2.0f);
+ TEST(nearbyint, 2.3f);
+ TEST(nearbyint, 2.5f);
+ TEST(nearbyint, 2.8f);
+
+ TEST(nearbyintf, 1.0f);
+ TEST(nearbyintf, 1.3f);
+ TEST(nearbyintf, 1.5f);
+ TEST(nearbyintf, 1.8f);
+
+ TEST(nearbyintf, 2.0f);
+ TEST(nearbyintf, 2.3f);
+ TEST(nearbyintf, 2.5f);
+ TEST(nearbyintf, 2.8f);
+
+ TEST(llrintf, 1.0f);
+ TEST(llrintf, 1.3f);
+ TEST(llrintf, 1.5f);
+ TEST(llrintf, 1.8f);
+
+ TEST(llrintf, 2.0f);
+ TEST(llrintf, 2.3f);
+ TEST(llrintf, 2.5f);
+ TEST(llrintf, 2.8f);
+
+ TEST(llrint, 1.0f);
+ TEST(llrint, 1.3f);
+ TEST(llrint, 1.5f);
+ TEST(llrint, 1.8f);
+
+ TEST(llrint, 2.0f);
+ TEST(llrint, 2.3f);
+ TEST(llrint, 2.5f);
+ TEST(llrint, 2.8f);
+
+ TEST(lrintf, 1.0f);
+ TEST(lrintf, 1.3f);
+ TEST(lrintf, 1.5f);
+ TEST(lrintf, 1.8f);
+
+ TEST(lrintf, 2.0f);
+ TEST(lrintf, 2.3f);
+ TEST(lrintf, 2.5f);
+ TEST(lrintf, 2.8f);
+
+ TEST(lrint, 1.0f);
+ TEST(lrint, 1.3f);
+ TEST(lrint, 1.5f);
+ TEST(lrint, 1.8f);
+
+ TEST(lrint, 2.0f);
+ TEST(lrint, 2.3f);
+ TEST(lrint, 2.5f);
+ TEST(lrint, 2.8f);
+
+ return 0;
+}
diff --git a/tests/test27 b/tests/test27
new file mode 100755
index 0000000..abe2daf
--- /dev/null
+++ b/tests/test27
Binary files differ
diff --git a/tests/test27.c b/tests/test27.c
new file mode 100644
index 0000000..37847e0
--- /dev/null
+++ b/tests/test27.c
@@ -0,0 +1,133 @@
+// build with gcc -O0 -g -msse -msse2 -mssse3 -msse4.1 -msse4.2 test27.c -o test27
+// and -m32 for 32bits version
+#include <inttypes.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <pmmintrin.h>
+#include <immintrin.h>
+
+typedef unsigned char u8x16 __attribute__ ((vector_size (16)));
+typedef unsigned short u16x8 __attribute__ ((vector_size (16)));
+typedef unsigned int u32x4 __attribute__ ((vector_size (16)));
+typedef unsigned long int u64x2 __attribute__ ((vector_size (16)));
+typedef float f32x4 __attribute__ ((vector_size (16)));
+typedef double d64x2 __attribute__ ((vector_size (16)));
+
+const char* string1 = "This is a string";
+const char* string2 = "This\0 string ";
+const char* string3 = "is\0 ";
+const char* string4 = "maestrum-foo-bar";
+const char* string5 = "\0 ";
+
+typedef union {
+ __m128i mm;
+ __m128 mf;
+ __m128d md;
+ u8x16 u8;
+ u16x8 u16;
+ u32x4 u32;
+ u64x2 u64;
+ f32x4 f32;
+ d64x2 d64;
+} v128;
+
+v128 load_string(const char* s)
+{
+ v128 ret;
+ for(int i=0; i<16; ++i)
+ ret.u8[i] = s[i];
+ return ret;
+}
+v128 load_stringw(const char* s)
+{
+ v128 ret;
+ for(int i=0; i<8; ++i)
+ ret.u16[i] = s[i];
+ return ret;
+}
+
+int main(int argc, const char** argv)
+{
+ printf("test SSE 4.2\n");
+
+ v128 a, b, c;
+ int ret;
+ int fa, fc, fo, fs, fz;
+ #define GO1(A, B, C) \
+ ret = _mm_cmpestri(a.mm, strlen(A), b.mm, strlen(B), C); \
+ printf("_mm_cmpestri(\"%s\", %d, \"%s\", %d, 0x%x) => %d\n", A, strlen(A), B, strlen(B), C, ret); \
+ fa = _mm_cmpestra(a.mm, strlen(A), b.mm, strlen(B), C); \
+ fc = _mm_cmpestrc(a.mm, strlen(A), b.mm, strlen(B), C); \
+ fo = _mm_cmpestro(a.mm, strlen(A), b.mm, strlen(B), C); \
+ fs = _mm_cmpestrs(a.mm, strlen(A), b.mm, strlen(B), C); \
+ fz = _mm_cmpestrz(a.mm, strlen(A), b.mm, strlen(B), C); \
+ printf("_mm_cmpestri(\"%s\", %d, \"%s\", %d, 0x%x) flags: a:%d s:%d z:%d c:%d o:%d\n", A, strlen(A), B, strlen(B), C, fa, fs, fz, fc, fo); \
+ c.mm = _mm_cmpestrm(a.mm, strlen(A), b.mm, strlen(B), C); \
+ printf("mm_cmpestrm(\"%s\", %d, \"%s\", %d, 0x%x) = %016x-%016x\n", A, strlen(A), B, strlen(B), C, c.u64[1], c.u64[0]); \
+ ret = _mm_cmpistri(a.mm, b.mm, C); \
+ printf("_mm_cmpistri(\"%s\", \"%s\", 0x%x) => %d\n", A, B, C, ret); \
+ fa = _mm_cmpistra(a.mm, b.mm, C); \
+ fc = _mm_cmpistrc(a.mm, b.mm, C); \
+ fo = _mm_cmpistro(a.mm, b.mm, C); \
+ fs = _mm_cmpistrs(a.mm, b.mm, C); \
+ fz = _mm_cmpistrz(a.mm, b.mm, C); \
+ printf("_mm_cmpestri(\"%s\", \"%s\", 0x%x) flags: a:%d s:%d z:%d c:%d o:%d\n", A, B, C, fa, fs, fz, fc, fo); \
+ c.mm = _mm_cmpistrm(a.mm, b.mm, C); \
+ printf("mm_cmpestrm(\"%s\", \"%s\", 0x%x) = %016x-%016x\n", A, B, C, c.u64[1], c.u64[0])
+
+ #define GO(A, B, C) \
+ a = load_string(A); \
+ b = load_string(B); \
+ GO1(A, B, C); \
+ a = load_stringw(A);\
+ b = load_stringw(B);\
+ GO1(A, B, C+1) \
+
+ #define GO2(C) \
+ GO(string1, string2, C); \
+ GO(string2, string1, C); \
+ GO(string1, string3, C); \
+ GO(string3, string1, C); \
+ GO(string1, string4, C); \
+ GO(string4, string1, C); \
+ GO(string1, string5, C); \
+ GO(string5, string1, C);
+
+ GO2(0x00)
+ GO2(0x04)
+ GO2(0x08)
+ GO2(0x0c)
+ GO2(0x10)
+ GO2(0x30)
+ GO2(0b1001100)
+ GO2(0b0101100)
+ GO2(0b0110100)
+ GO2(0b0110110)
+ GO2(0b1110100)
+
+ unsigned int crc = 0;
+ printf("crc32(0x%x, byte:0x%x) => ", crc, 0);
+ crc = _mm_crc32_u8(crc, 0);
+ printf("0x%x\n", crc);
+ printf("crc32(0x%x, byte:0x%x) => ", crc, 10);
+ crc = _mm_crc32_u8(crc, 10);
+ printf("0x%x\n", crc);
+ printf("crc32(0x%x, dword:0x%x) => ", crc, 0);
+ crc = _mm_crc32_u32(crc, 0);
+ printf("0x%x\n", crc);
+ printf("crc32(0x%x, dword:0x%x) => ", crc, 0x123456);
+ crc = _mm_crc32_u32(crc, 0x123456);
+ printf("0x%x\n", crc);
+ printf("crc32(0x%x, word:0x%x) => ", crc, 0x8765);
+ crc = _mm_crc32_u16(crc, 0x8765);
+ printf("0x%x\n", crc);
+ printf("crc32(0x%x, qword:0x%x) => ", crc, 0xff1234567890);
+ uint64_t crc64 = _mm_crc32_u64(crc, 0xff1234567890);
+ printf("0x%x\n", crc64);
+
+ return 0;
+}
diff --git a/tests/test28 b/tests/test28
new file mode 100755
index 0000000..43aee28
--- /dev/null
+++ b/tests/test28
Binary files differ
diff --git a/tests/test28.c b/tests/test28.c
new file mode 100644
index 0000000..86df4a9
--- /dev/null
+++ b/tests/test28.c
@@ -0,0 +1,134 @@
+// build with gcc -O0 -g -msha -msse4.2 test28.c -o test28
+// and -m32 for 32bits version
+#include <inttypes.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <pmmintrin.h>
+#include <immintrin.h>
+
+typedef unsigned char u8x16 __attribute__ ((vector_size (16)));
+typedef unsigned short u16x8 __attribute__ ((vector_size (16)));
+typedef unsigned int u32x4 __attribute__ ((vector_size (16)));
+typedef unsigned long int u64x2 __attribute__ ((vector_size (16)));
+typedef float f32x4 __attribute__ ((vector_size (16)));
+typedef double d64x2 __attribute__ ((vector_size (16)));
+
+typedef union {
+ __m128i mm;
+ __m128 mf;
+ __m128d md;
+ u8x16 u8;
+ u16x8 u16;
+ u32x4 u32;
+ u64x2 u64;
+ f32x4 f32;
+ d64x2 d64;
+} v128;
+
+static const uint32_t A[] = {0, 0, 0, 0};
+static const uint32_t B[] = {1, 2, 3, 4};
+static const uint32_t C[] = {0x80000000, 0x1234567, 0, 0xffffffff};
+
+static void print_u32(v128 a) {
+ printf("%08x-%08x-%08x-%08x", a.u32[3], a.u32[2], a.u32[1], a.u32[0]);
+}
+
+static void print_u32_res(v128 a, v128 b, const char* op, v128 res) {
+ printf("%s(", op);
+ print_u32(a);
+ printf(" ,");
+ print_u32(b);
+ printf(") => ");
+ print_u32(res);
+ printf("\n");
+}
+static void print_u32_u8_res(v128 a, v128 b, const char* op, uint8_t ib, v128 res) {
+ printf("%s(", op);
+ print_u32(a);
+ printf(" ,");
+ print_u32(b);
+ printf(", 0x%x) => ", ib);
+ print_u32(res);
+ printf("\n");
+}
+
+static void print_3u32_res(v128 a, v128 b, v128 c, const char* op, v128 res) {
+ printf("%s(", op);
+ print_u32(a);
+ printf(" ,");
+ print_u32(b);
+ printf(" ,");
+ print_u32(c);
+ printf(") => ");
+ print_u32(res);
+ printf("\n");
+}
+
+int main(int argc, const char** argv)
+{
+ printf("test SHA Ext\n");
+
+ v128 a, b, c, d;
+ int ret;
+ #define LOAD(a, A) a.u32[0] = A[0]; a.u32[1] = A[1]; a.u32[2] = A[2]; a.u32[3] = A[3]
+
+ #define GO2I_(A, B, C, I) \
+ LOAD(a, A); \
+ LOAD(b, B); \
+ c.mm = _mm_##C##_epu32(a.mm, b.mm, I); \
+ print_u32_u8_res(a, b, #C, I, c)
+
+ #define GO2(A, B, C) \
+ LOAD(a, A); \
+ LOAD(b, B); \
+ c.mm = _mm_##C##_epu32(a.mm, b.mm); \
+ print_u32_res(a, b, #C, c)
+
+ #define GO3(A, B, C, D) \
+ LOAD(a, A); \
+ LOAD(b, B); \
+ LOAD(c, C); \
+ d.mm = _mm_##D##_epu32(a.mm, b.mm, c.mm); \
+ print_3u32_res(a, b, c, #D, d)
+
+
+ #define GO2I(A, B, C) \
+ GO2I_(A, B, C, 0x00); \
+ GO2I_(A, B, C, 0x01); \
+ GO2I_(A, B, C, 0x02); \
+ GO2I_(A, B, C, 0x03)
+
+ GO2I(A, B, sha1rnds4);
+ GO2I(A, C, sha1rnds4);
+ GO2I(B, C, sha1rnds4);
+
+ GO2(A, B, sha1msg1);
+ GO2(A, C, sha1msg1);
+ GO2(B, C, sha1msg1);
+
+ GO2(A, B, sha1msg2);
+ GO2(A, C, sha1msg2);
+ GO2(B, C, sha1msg2);
+
+ GO2(A, B, sha1nexte);
+ GO2(A, C, sha1nexte);
+ GO2(B, C, sha1nexte);
+
+ GO2(A, B, sha256msg1);
+ GO2(A, C, sha256msg1);
+ GO2(B, C, sha256msg1);
+
+ GO2(A, B, sha256msg2);
+ GO2(A, C, sha256msg2);
+ GO2(B, C, sha256msg2);
+
+ GO3(A, B, C, sha256rnds2);
+ GO3(B, A, C, sha256rnds2);
+ GO3(C, B, A, sha256rnds2);
+
+ return 0;
+}
diff --git a/tests/test29 b/tests/test29
new file mode 100755
index 0000000..0c4a63d
--- /dev/null
+++ b/tests/test29
Binary files differ
diff --git a/tests/test29.c b/tests/test29.c
new file mode 100644
index 0000000..9638425
--- /dev/null
+++ b/tests/test29.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdint.h>
+// Build with `gcc -march=core2 -O0 test29.c -o test29`
+
+uint64_t lock_xadd(uint64_t Gd, uint64_t volatile* Ed) {
+uint64_t Res;
+asm(
+"lock xadd %[_Gd], (%[_Ed])\n"
+"movq %[_Gd], %[_Res]\n"
+: [_Res] "+r"(Res)
+: [_Gd] "r"(Gd)
+, [_Ed] "r"(Ed)
+);
+return Res;
+}
+
+uint64_t lock_xchg(uint64_t Gd, uint64_t volatile* Ed) {
+uint64_t Res;
+asm(
+"lock xchg %[_Gd], (%[_Ed])\n"
+"movq %[_Gd], %[_Res]\n"
+: [_Res] "+r"(Res)
+: [_Gd] "r"(Gd)
+, [_Ed] "r"(Ed)
+);
+return Res;
+}
+
+int main() {
+uint64_t Gd = 0x123;
+uint64_t volatile Ed = 0x456;
+uint64_t Res = lock_xadd(Gd, &Ed);
+printf("Lock XADD: Res = 0x%lx, Ed = 0x%lx\n", Res, Ed);
+Gd = 0x123;
+Res = lock_xchg(Gd, &Ed);
+printf("Lock XCHG: Res = 0x%lx, Ed = 0x%lx\n", Res, Ed);
+return 0;
+}