├── .clang-format ├── .gitignore ├── CMakeLists.txt ├── CREDITS.txt ├── LICENSE ├── LICENSE.LESSER ├── LICENSE.MIT ├── android_fuzz_runner.sh ├── android_test_runner.sh ├── arch └── simd │ └── rsp │ ├── SSE2NEON.h │ ├── clamp.h │ ├── rsp_common.h │ ├── rsp_core.cpp │ ├── rsp_impl.h │ ├── vabs.h │ ├── vadd.h │ ├── vaddc.h │ ├── vand.h │ ├── vch.h │ ├── vcl.h │ ├── vcmp.h │ ├── vcr.h │ ├── vdivh.h │ ├── vmac.h │ ├── vmrg.h │ ├── vmudh.h │ ├── vmul.h │ ├── vmulh.h │ ├── vmull.h │ ├── vmulm.h │ ├── vmuln.h │ ├── vor.h │ ├── vrcpsq.h │ ├── vrsq.h │ ├── vsub.h │ ├── vsubc.h │ └── vxor.h ├── build_android_aarch64.sh ├── build_native.sh ├── compare_test_results.sh ├── cpu_state.hpp ├── debug-toolchain ├── Makefile ├── Makefile.mips ├── add.s ├── addi.s ├── and.s ├── andi.s ├── beq-impossible-delay-slot-both-taken.s ├── beq-impossible-delay-slot-first-taken.s ├── beq-impossible-delay-slot-second-taken.s ├── bgez.s ├── bgezal.s ├── bgtz.s ├── blez.s ├── bltz.s ├── bltzal.s ├── bne.s ├── bug-shl-into-branch.s ├── cop0.s ├── cop2-basic.s ├── cop2-ls.s ├── cop2-vector.s ├── delay-slot-before-break.s ├── delay-slot-before-new-block-illegal.s ├── delay-slot-before-new-block-not-taken.s ├── delay-slot-before-new-block.s ├── j.s ├── jal-into-indirect-delay-slot.s ├── jal.s ├── jalr.s ├── jr.s ├── lb.s ├── lbu.s ├── lh-unaligned.s ├── lh.s ├── lhu-unaligned.s ├── lhu.s ├── lui.s ├── lw-unaligned-in-branch-delay.s ├── lw-unaligned.s ├── lw.s ├── main.c ├── nor.s ├── or.s ├── ori.s ├── rsp-mips.h ├── rsp-mips.ld ├── rsp-mips.s ├── sb.s ├── sh-unaligned.s ├── sh.s ├── sll.s ├── sllv.s ├── slt.s ├── slti.s ├── sltiu.s ├── sltu.s ├── sra.s ├── srav.s ├── srl.s ├── srlv.s ├── start.s ├── sub.s ├── sw-unaligned.s ├── sw.s ├── unconditional-delay-slot-before-break.s ├── xor.s └── xori.s ├── debug_jit.cpp ├── debug_jit.hpp ├── debug_rsp.cpp ├── debug_rsp.hpp ├── format_all.sh ├── jit_allocator.cpp ├── jit_allocator.hpp ├── lightning ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .gitrepo ├── AUTHORS ├── COPYING ├── COPYING.DOC ├── COPYING.LESSER ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── README-hacking ├── THANKS ├── TODO ├── bootstrap ├── bootstrap.conf ├── check │ ├── .gitignore │ ├── 3to2.ok │ ├── 3to2.tst │ ├── Makefile.am │ ├── add.ok │ ├── add.tst │ ├── align.ok │ ├── align.tst │ ├── all.tst │ ├── allocai.ok │ ├── allocai.tst │ ├── allocar.ok │ ├── allocar.tst │ ├── alu.inc │ ├── alu_add.ok │ ├── alu_add.tst │ ├── alu_and.ok │ ├── alu_and.tst │ ├── alu_com.ok │ ├── alu_com.tst │ ├── alu_div.ok │ ├── alu_div.tst │ ├── alu_lsh.ok │ ├── alu_lsh.tst │ ├── alu_mul.ok │ ├── alu_mul.tst │ ├── alu_neg.ok │ ├── alu_neg.tst │ ├── alu_or.ok │ ├── alu_or.tst │ ├── alu_rem.ok │ ├── alu_rem.tst │ ├── alu_rsb.ok │ ├── alu_rsb.tst │ ├── alu_rsh.ok │ ├── alu_rsh.tst │ ├── alu_sub.ok │ ├── alu_sub.tst │ ├── alu_xor.ok │ ├── alu_xor.tst │ ├── alux_add.ok │ ├── alux_add.tst │ ├── alux_sub.ok │ ├── alux_sub.tst │ ├── bit.ok │ ├── bit.tst │ ├── bp.ok │ ├── bp.tst │ ├── branch.ok │ ├── branch.tst │ ├── bswap.ok │ ├── bswap.tst │ ├── call.ok │ ├── call.tst │ ├── carg.c │ ├── carry.ok │ ├── carry.tst │ ├── catomic.c │ ├── catomic.ok │ ├── ccall.c │ ├── check.arm.sh │ ├── check.arm.swf.sh │ ├── check.arm4.swf.sh │ ├── check.nodata.sh │ ├── check.sh │ ├── check.swf.sh │ ├── check.x87.nodata.sh │ ├── check.x87.sh │ ├── clobber.ok │ ├── clobber.tst │ ├── collatz.tst │ ├── ctramp.c │ ├── cva_list.c │ ├── cvt.ok │ ├── cvt.tst │ ├── divi.ok │ ├── divi.tst │ ├── factorial.tst │ ├── fib.ok │ ├── fib.tst │ ├── float.ok │ ├── float.tst │ ├── fop_abs.ok │ ├── fop_abs.tst │ ├── fop_sqrt.ok │ ├── fop_sqrt.tst │ ├── hton.ok │ ├── hton.tst │ ├── jmpr.ok │ ├── jmpr.tst │ ├── ldst.inc │ ├── ldsti.ok │ ├── ldsti.tst │ ├── ldstr-c.ok │ ├── ldstr-c.tst │ ├── ldstr.ok │ ├── ldstr.tst │ ├── ldstxi-c.ok │ ├── ldstxi-c.tst │ ├── ldstxi.ok │ ├── ldstxi.tst │ ├── ldstxr-c.ok │ ├── ldstxr-c.tst │ ├── ldstxr.ok │ ├── ldstxr.tst │ ├── lightning.c │ ├── live.ok │ ├── live.tst │ ├── movzr.ok │ ├── movzr.tst │ ├── nodata.c │ ├── protect.c │ ├── put.ok │ ├── put.tst │ ├── qalu.inc │ ├── qalu_div.ok │ ├── qalu_div.tst │ ├── qalu_mul.ok │ ├── qalu_mul.tst │ ├── range.ok │ ├── range.tst │ ├── ranger.ok │ ├── ranger.tst │ ├── ret.ok │ ├── ret.tst │ ├── riprel.c │ ├── riprel.ok │ ├── rpn.ok │ ├── rpn.tst │ ├── run-test │ ├── self.c │ ├── setcode.c │ ├── skip.ok │ ├── skip.tst │ ├── stack.ok │ ├── stack.tst │ ├── tramp.ok │ ├── tramp.tst │ ├── va_list.ok │ ├── va_list.tst │ ├── varargs.ok │ └── varargs.tst ├── configure.ac ├── doc │ ├── .cvsignore │ ├── .gitignore │ ├── Makefile.am │ ├── body.texi │ ├── fact.c │ ├── ifib.c │ ├── incr.c │ ├── lightning.texi │ ├── printf.c │ ├── rfib.c │ └── rpn.c ├── gnulib-lib │ └── .gitignore ├── include │ ├── Makefile.am │ ├── lightning.h │ ├── lightning.h.in │ └── lightning │ │ ├── Makefile.am │ │ ├── jit_aarch64.h │ │ ├── jit_alpha.h │ │ ├── jit_arm.h │ │ ├── jit_hppa.h │ │ ├── jit_ia64.h │ │ ├── jit_loongarch.h │ │ ├── jit_mips.h │ │ ├── jit_ppc.h │ │ ├── jit_private.h │ │ ├── jit_riscv.h │ │ ├── jit_s390.h │ │ ├── jit_sparc.h │ │ └── jit_x86.h ├── lib │ ├── Makefile.am │ ├── aarch64-logical-immediates.c │ ├── jit_aarch64-cpu.c │ ├── jit_aarch64-fpu.c │ ├── jit_aarch64-sz.c │ ├── jit_aarch64.c │ ├── jit_alpha-cpu.c │ ├── jit_alpha-fpu.c │ ├── jit_alpha-sz.c │ ├── jit_alpha.c │ ├── jit_arm-cpu.c │ ├── jit_arm-swf.c │ ├── jit_arm-sz.c │ ├── jit_arm-vfp.c │ ├── jit_arm.c │ ├── jit_disasm.c │ ├── jit_fallback.c │ ├── jit_hppa-cpu.c │ ├── jit_hppa-fpu.c │ ├── jit_hppa-sz.c │ ├── jit_hppa.c │ ├── jit_ia64-cpu.c │ ├── jit_ia64-fpu.c │ ├── jit_ia64-sz.c │ ├── jit_ia64.c │ ├── jit_loongarch-cpu.c │ ├── jit_loongarch-fpu.c │ ├── jit_loongarch-sz.c │ ├── jit_loongarch.c │ ├── jit_memory.c │ ├── jit_mips-cpu.c │ ├── jit_mips-fpu.c │ ├── jit_mips-sz.c │ ├── jit_mips.c │ ├── jit_names.c │ ├── jit_note.c │ ├── jit_ppc-cpu.c │ ├── jit_ppc-fpu.c │ ├── jit_ppc-sz.c │ ├── jit_ppc.c │ ├── jit_print.c │ ├── jit_rewind.c │ ├── jit_riscv-cpu.c │ ├── jit_riscv-fpu.c │ ├── jit_riscv-sz.c │ ├── jit_riscv.c │ ├── jit_s390-cpu.c │ ├── jit_s390-fpu.c │ ├── jit_s390-sz.c │ ├── jit_s390.c │ ├── jit_size.c │ ├── jit_sparc-cpu.c │ ├── jit_sparc-fpu.c │ ├── jit_sparc-sz.c │ ├── jit_sparc.c │ ├── jit_x86-cpu.c │ ├── jit_x86-sse.c │ ├── jit_x86-sz.c │ ├── jit_x86-x87.c │ ├── jit_x86.c │ └── lightning.c ├── lightning.pc.in ├── m4 │ ├── .gitignore │ ├── .gitkeep │ └── gnulib-cache.m4 └── size.c ├── llvm_jit.cpp ├── llvm_jit.hpp ├── main.cpp ├── parallel.cpp ├── rsp ├── cp0.cpp ├── cp2.cpp ├── ls.cpp ├── pipeline.h ├── reciprocal.cpp ├── reciprocal.h ├── registers.md └── vfunctions.cpp ├── rsp_1.1.h ├── rsp_disasm.cpp ├── rsp_disasm.hpp ├── rsp_jit.cpp ├── rsp_jit.hpp ├── rsp_op.hpp ├── rsp_vu_fuzzer.cpp ├── state.hpp └── win32 └── mman └── sys ├── .gitignore ├── .gitrepo ├── .vs └── mman │ └── v14 │ └── .suo ├── CMakeLists.txt ├── Makefile ├── README.md ├── UpgradeLog.htm ├── configure ├── mman-win32.pro ├── mman.c ├── mman.h ├── mman.sln ├── mman.vcxproj ├── mman.vcxproj.filters ├── mman.vcxproj.user └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | *.bin 4 | *.elf 5 | /cmake-build-* 6 | /.idea 7 | *.iml 8 | /build-* 9 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | Written by Themaister. 2 | 3 | The code is heavily reliant on MarathonMan's CEN64 RSP implementation, as well as Ares and CXD4's RSP implementations. 4 | 5 | MIPS core: Rewritten from scratch 6 | CP0: Near copy-pasta from CEN64, with some fixes from Ares brought in 7 | CP2: Near copy-pasta from CEN64 8 | LS pipe: Ported from Ares 9 | Mupen64plus glue code: Reused most of CXD4. 10 | Lightning jitter interface: Written from scratch 11 | 12 | The plugin's focus is to support dynamic recompilation for performance, 13 | instead of being pure interpreters as CEN64 and CXD4's implementations are. 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ============== 2 | parallel-rsp 3 | ============== 4 | 5 | This project is dual licensed under 6 | 7 | MIT (LICENSE.MIT) 8 | 9 | or 10 | 11 | LGPLv3 (LICENSE.LESSER) 12 | 13 | If statically linking against the GNU Lightning project (lightning/), 14 | note that Lightning is dual-licensed as GPLv3 or LGPLv3. 15 | parallel-rsp can be configured to dynamically link against Lightning or not link against Lightning at all. 16 | 17 | -------------------------------------------------------------------------------- /LICENSE.MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Hans-Kristian Arntzen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /android_fuzz_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RSP_FUZZ="$1" 4 | 5 | adb push "$RSP_FUZZ" /data/local/tmp/rsp-vu-fuzzer >/dev/null || exit 1 6 | adb shell chmod +x /data/local/tmp/rsp-vu-fuzzer >/dev/null || exit 1 7 | adb shell /data/local/tmp/rsp-vu-fuzzer || exit 1 8 | adb shell rm /data/local/tmp/rsp-vu-fuzzer || exit 1 9 | -------------------------------------------------------------------------------- /android_test_runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RSP_RUNNER="$1" 4 | RSP_BINFOLDER="$2" 5 | TEST_NAME="$3" 6 | 7 | adb push "$RSP_RUNNER" /data/local/tmp/rsp-runner >/dev/null || exit 1 8 | adb shell chmod +x /data/local/tmp/rsp-runner >/dev/null || exit 1 9 | adb push "$RSP_BINFOLDER"/"$TEST_NAME".global.bin /data/local/tmp/ >/dev/null || exit 1 10 | adb push "$RSP_BINFOLDER"/"$TEST_NAME".bin /data/local/tmp/ >/dev/null || exit 1 11 | adb shell /data/local/tmp/rsp-runner /data/local/tmp/"$TEST_NAME".global.bin /data/local/tmp/"$TEST_NAME".bin || exit 1 12 | adb shell rm /data/local/tmp/rsp-runner >/dev/null || exit 1 13 | adb shell rm /data/local/tmp/"$TEST_NAME".global.bin /data/local/tmp/"$TEST_NAME".bin >/dev/null || exit 1 14 | -------------------------------------------------------------------------------- /arch/simd/rsp/clamp.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/clamp.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_sclamp_acc_tomd(__m128i acc_md, __m128i acc_hi) 9 | { 10 | __m128i l = _mm_unpacklo_epi16(acc_md, acc_hi); 11 | __m128i h = _mm_unpackhi_epi16(acc_md, acc_hi); 12 | return _mm_packs_epi32(l, h); 13 | } 14 | 15 | static inline __m128i rsp_uclamp_acc(__m128i val, __m128i acc_md, __m128i acc_hi, __m128i zero) 16 | { 17 | __m128i clamp_mask, clamped_val; 18 | __m128i hi_sign_check, md_sign_check; 19 | __m128i md_negative, hi_negative; 20 | __m128i tmp; 21 | 22 | hi_negative = _mm_srai_epi16(acc_hi, 15); 23 | md_negative = _mm_srai_epi16(acc_md, 15); 24 | 25 | // We don't have to clamp if the HI part of the 26 | // accumulator is sign-extended down to the MD part. 27 | hi_sign_check = _mm_cmpeq_epi16(hi_negative, acc_hi); 28 | md_sign_check = _mm_cmpeq_epi16(hi_negative, md_negative); 29 | clamp_mask = _mm_and_si128(md_sign_check, hi_sign_check); 30 | 31 | // Generate the value in the event we need to clamp. 32 | // * hi_negative, mid_sign => xxxx 33 | // * hi_negative, !mid_sign => 0000 34 | // * !hi_negative, mid_sign => FFFF 35 | // * !hi_negative, !mid_sign => xxxx 36 | clamped_val = _mm_cmpeq_epi16(hi_negative, zero); 37 | 38 | #ifndef __SSE4_1__ 39 | tmp = _mm_and_si128(clamp_mask, val); 40 | val = _mm_andnot_si128(clamp_mask, clamped_val); 41 | return _mm_or_si128(val, tmp); 42 | #else 43 | return _mm_blendv_epi8(clamped_val, val, clamp_mask); 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /arch/simd/rsp/rsp_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef RSP_IMPL_H 2 | #define RSP_IMPL_H 3 | 4 | #include "clamp.h" 5 | #include "vabs.h" 6 | #include "vadd.h" 7 | #include "vaddc.h" 8 | #include "vand.h" 9 | #include "vch.h" 10 | #include "vcl.h" 11 | #include "vcmp.h" 12 | #include "vcr.h" 13 | #include "vdivh.h" 14 | #include "vmac.h" 15 | #include "vmrg.h" 16 | #include "vmul.h" 17 | #include "vmulh.h" 18 | #include "vmull.h" 19 | #include "vmulm.h" 20 | #include "vmuln.h" 21 | #include "vor.h" 22 | #include "vrcpsq.h" 23 | #include "vrsq.h" 24 | #include "vsub.h" 25 | #include "vsubc.h" 26 | #include "vxor.h" 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /arch/simd/rsp/vabs.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vabs.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vabs(__m128i vs, __m128i vt, __m128i *acc_lo) 9 | { 10 | __m128i vs_zero = _mm_cmpeq_epi16(vs, _mm_setzero_si128()); 11 | __m128i sign_lt = _mm_srai_epi16(vs, 15); 12 | __m128i vd = _mm_andnot_si128(vs_zero, vt); 13 | 14 | // Careful: if VT = 0x8000 and VS is negative, 15 | // acc_lo will be 0x8000 but vd will be 0x7FFF. 16 | vd = _mm_xor_si128(vd, sign_lt); 17 | *acc_lo = _mm_sub_epi16(vd, sign_lt); 18 | return _mm_subs_epi16(vd, sign_lt); 19 | } 20 | -------------------------------------------------------------------------------- /arch/simd/rsp/vadd.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vadd.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vadd(__m128i vs, __m128i vt, __m128i carry, __m128i *acc_lo) 9 | { 10 | __m128i vd, minimum, maximum; 11 | 12 | // VCC uses unsaturated arithmetic. 13 | vd = _mm_add_epi16(vs, vt); 14 | *acc_lo = _mm_sub_epi16(vd, carry); 15 | 16 | // VD is the signed sum of the two sources and the carry. Since we 17 | // have to saturate the sum of all three, we have to be clever. 18 | minimum = _mm_min_epi16(vs, vt); 19 | maximum = _mm_max_epi16(vs, vt); 20 | minimum = _mm_subs_epi16(minimum, carry); 21 | return _mm_adds_epi16(minimum, maximum); 22 | } 23 | -------------------------------------------------------------------------------- /arch/simd/rsp/vaddc.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vaddc.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vaddc(__m128i vs, __m128i vt, __m128i zero, __m128i *sn) 9 | { 10 | __m128i sat_sum, unsat_sum; 11 | 12 | sat_sum = _mm_adds_epu16(vs, vt); 13 | unsat_sum = _mm_add_epi16(vs, vt); 14 | 15 | *sn = _mm_cmpeq_epi16(sat_sum, unsat_sum); 16 | *sn = _mm_cmpeq_epi16(*sn, zero); 17 | 18 | return unsat_sum; 19 | } 20 | -------------------------------------------------------------------------------- /arch/simd/rsp/vand.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vand.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vand(__m128i vs, __m128i vt) 9 | { 10 | return _mm_and_si128(vs, vt); 11 | } 12 | 13 | static inline __m128i rsp_vnand(__m128i vs, __m128i vt) 14 | { 15 | __m128i vd = _mm_and_si128(vs, vt); 16 | return _mm_xor_si128(vd, _mm_set1_epi32(0xffffffffu)); 17 | } 18 | -------------------------------------------------------------------------------- /arch/simd/rsp/vch.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vch.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vch(__m128i vs, __m128i vt, __m128i zero, __m128i *ge, __m128i *le, __m128i *eq, 9 | __m128i *sign, __m128i *vce) 10 | { 11 | 12 | __m128i sign_negvt, vt_neg; 13 | __m128i diff, diff_zero, diff_sel_mask; 14 | __m128i diff_gez, diff_lez; 15 | 16 | // sign = (vs ^ vt) < 0 17 | *sign = _mm_xor_si128(vs, vt); 18 | *sign = _mm_cmplt_epi16(*sign, zero); 19 | 20 | // sign_negvt = sign ? -vt : vt 21 | sign_negvt = _mm_xor_si128(vt, *sign); 22 | sign_negvt = _mm_sub_epi16(sign_negvt, *sign); 23 | 24 | // Compute diff, diff_zero: 25 | diff = _mm_sub_epi16(vs, sign_negvt); 26 | diff_zero = _mm_cmpeq_epi16(diff, zero); 27 | 28 | // Compute le/ge: 29 | vt_neg = _mm_cmplt_epi16(vt, zero); 30 | diff_lez = _mm_cmpgt_epi16(diff, zero); 31 | diff_gez = _mm_or_si128(diff_lez, diff_zero); 32 | diff_lez = _mm_cmpeq_epi16(zero, diff_lez); 33 | 34 | #ifdef __SSE4_1__ 35 | *ge = _mm_blendv_epi8(diff_gez, vt_neg, *sign); 36 | *le = _mm_blendv_epi8(vt_neg, diff_lez, *sign); 37 | #else 38 | *ge = _mm_and_si128(*sign, vt_neg); 39 | diff_gez = _mm_andnot_si128(*sign, diff_gez); 40 | *ge = _mm_or_si128(*ge, diff_gez); 41 | 42 | *le = _mm_and_si128(*sign, diff_lez); 43 | diff_lez = _mm_andnot_si128(*sign, vt_neg); 44 | *le = _mm_or_si128(*le, diff_lez); 45 | #endif 46 | 47 | // Compute vce: 48 | *vce = _mm_cmpeq_epi16(diff, *sign); 49 | *vce = _mm_and_si128(*vce, *sign); 50 | 51 | // Compute !eq: 52 | *eq = _mm_or_si128(diff_zero, *vce); 53 | *eq = _mm_cmpeq_epi16(*eq, zero); 54 | 55 | // Compute result: 56 | #ifdef __SSE4_1__ 57 | diff_sel_mask = _mm_blendv_epi8(*ge, *le, *sign); 58 | return _mm_blendv_epi8(vs, sign_negvt, diff_sel_mask); 59 | #else 60 | diff_lez = _mm_and_si128(*sign, *le); 61 | diff_gez = _mm_andnot_si128(*sign, *ge); 62 | diff_sel_mask = _mm_or_si128(diff_lez, diff_gez); 63 | 64 | diff_lez = _mm_and_si128(diff_sel_mask, sign_negvt); 65 | diff_gez = _mm_andnot_si128(diff_sel_mask, vs); 66 | return _mm_or_si128(diff_lez, diff_gez); 67 | #endif 68 | } 69 | -------------------------------------------------------------------------------- /arch/simd/rsp/vcl.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vcl.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vcl(__m128i vs, __m128i vt, __m128i zero, __m128i *ge, __m128i *le, __m128i eq, __m128i sign, 9 | __m128i vce) 10 | { 11 | 12 | __m128i sign_negvt, diff, ncarry, nvce, diff_zero; 13 | __m128i le_case1, le_case2, le_eq, do_le; 14 | __m128i ge_eq, do_ge, mux_mask; 15 | 16 | // sign_negvt = sign ? -vt : vt 17 | sign_negvt = _mm_xor_si128(vt, sign); 18 | sign_negvt = _mm_sub_epi16(sign_negvt, sign); 19 | 20 | // Compute diff, diff_zero, ncarry, and nvce: 21 | // Note: diff = sign ? (vs + vt) : (vs - vt). 22 | diff = _mm_sub_epi16(vs, sign_negvt); 23 | ncarry = _mm_adds_epu16(vs, vt); 24 | ncarry = _mm_cmpeq_epi16(diff, ncarry); 25 | nvce = _mm_cmpeq_epi16(vce, zero); 26 | diff_zero = _mm_cmpeq_epi16(diff, zero); 27 | 28 | // Compute results for if (sign && ne): 29 | le_case1 = _mm_and_si128(diff_zero, ncarry); 30 | le_case1 = _mm_and_si128(nvce, le_case1); 31 | le_case2 = _mm_or_si128(diff_zero, ncarry); 32 | le_case2 = _mm_and_si128(vce, le_case2); 33 | le_eq = _mm_or_si128(le_case1, le_case2); 34 | 35 | // Compute results for if (!sign && ne): 36 | ge_eq = _mm_subs_epu16(vt, vs); 37 | ge_eq = _mm_cmpeq_epi16(ge_eq, zero); 38 | 39 | // Blend everything together. Caveat: we don't update 40 | // the results of ge/le if ne is false, so be careful. 41 | do_le = _mm_andnot_si128(eq, sign); 42 | #ifdef __SSE4_1__ 43 | *le = _mm_blendv_epi8(*le, le_eq, do_le); 44 | #else 45 | le_eq = _mm_and_si128(do_le, le_eq); 46 | *le = _mm_andnot_si128(do_le, *le); 47 | *le = _mm_or_si128(le_eq, *le); 48 | #endif 49 | 50 | do_ge = _mm_or_si128(sign, eq); 51 | #ifdef __SSE4_1__ 52 | *ge = _mm_blendv_epi8(ge_eq, *ge, do_ge); 53 | #else 54 | *ge = _mm_and_si128(do_ge, *ge); 55 | ge_eq = _mm_andnot_si128(do_ge, ge_eq); 56 | *ge = _mm_or_si128(ge_eq, *ge); 57 | #endif 58 | 59 | // Mux the result based on the value of sign. 60 | #ifdef __SSE4_1__ 61 | mux_mask = _mm_blendv_epi8(*ge, *le, sign); 62 | #else 63 | do_le = _mm_and_si128(sign, *le); 64 | do_ge = _mm_andnot_si128(sign, *ge); 65 | mux_mask = _mm_or_si128(do_le, do_ge); 66 | #endif 67 | 68 | #ifdef __SSE4_1__ 69 | return _mm_blendv_epi8(vs, sign_negvt, mux_mask); 70 | #else 71 | sign_negvt = _mm_and_si128(mux_mask, sign_negvt); 72 | vs = _mm_andnot_si128(mux_mask, vs); 73 | return _mm_or_si128(sign_negvt, vs); 74 | #endif 75 | } 76 | -------------------------------------------------------------------------------- /arch/simd/rsp/vcmp.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vcmp.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_veq(__m128i vs, __m128i vt, __m128i zero, __m128i *le, __m128i eq, __m128i sign) 9 | { 10 | __m128i equal = _mm_cmpeq_epi16(vs, vt); 11 | 12 | *le = _mm_andnot_si128(eq, equal); 13 | 14 | #ifdef __SSE4_1__ 15 | return _mm_blendv_epi8(vt, vs, *le); 16 | #else 17 | vs = _mm_and_si128(*le, vs); 18 | vt = _mm_andnot_si128(*le, vt); 19 | return _mm_or_si128(vs, vt); 20 | #endif 21 | } 22 | 23 | static inline __m128i rsp_vge(__m128i vs, __m128i vt, __m128i zero, __m128i *le, __m128i eq, __m128i sign) 24 | { 25 | __m128i equal = _mm_cmpeq_epi16(vs, vt); 26 | 27 | __m128i gt = _mm_cmpgt_epi16(vs, vt); 28 | __m128i equalsign = _mm_and_si128(eq, sign); 29 | 30 | equal = _mm_andnot_si128(equalsign, equal); 31 | *le = _mm_or_si128(gt, equal); 32 | 33 | #ifdef __SSE4_1__ 34 | return _mm_blendv_epi8(vt, vs, *le); 35 | #else 36 | vs = _mm_and_si128(*le, vs); 37 | vt = _mm_andnot_si128(*le, vt); 38 | return _mm_or_si128(vs, vt); 39 | #endif 40 | } 41 | 42 | static inline __m128i rsp_vlt(__m128i vs, __m128i vt, __m128i zero, __m128i *le, __m128i eq, __m128i sign) 43 | { 44 | __m128i equal = _mm_cmpeq_epi16(vs, vt); 45 | __m128i lt = _mm_cmplt_epi16(vs, vt); 46 | 47 | equal = _mm_and_si128(eq, equal); 48 | equal = _mm_and_si128(sign, equal); 49 | *le = _mm_or_si128(lt, equal); 50 | 51 | #ifdef __SSE4_1__ 52 | return _mm_blendv_epi8(vt, vs, *le); 53 | #else 54 | vs = _mm_and_si128(*le, vs); 55 | vt = _mm_andnot_si128(*le, vt); 56 | return _mm_or_si128(vs, vt); 57 | #endif 58 | } 59 | 60 | static inline __m128i rsp_vne(__m128i vs, __m128i vt, __m128i zero, __m128i *le, __m128i eq, __m128i sign) 61 | { 62 | __m128i equal = _mm_cmpeq_epi16(vs, vt); 63 | __m128i nequal = _mm_cmpeq_epi16(equal, zero); 64 | 65 | *le = _mm_and_si128(eq, equal); 66 | *le = _mm_or_si128(*le, nequal); 67 | 68 | #ifdef INTENSE_DEBUG 69 | for (unsigned i = 0; i < 8; i++) 70 | fprintf(stderr, "VS[%d] = %d\n", i, reinterpret_cast(&vs)[i]); 71 | for (unsigned i = 0; i < 8; i++) 72 | fprintf(stderr, "VT[%d] = %d\n", i, reinterpret_cast(&vt)[i]); 73 | #endif 74 | 75 | #ifdef __SSE4_1__ 76 | return _mm_blendv_epi8(vt, vs, *le); 77 | #else 78 | vs = _mm_and_si128(*le, vs); 79 | vt = _mm_andnot_si128(*le, vt); 80 | return _mm_or_si128(vs, vt); 81 | #endif 82 | } 83 | -------------------------------------------------------------------------------- /arch/simd/rsp/vcr.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vcr.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vcr(__m128i vs, __m128i vt, __m128i zero, __m128i *ge, __m128i *le) 9 | { 10 | __m128i diff_sel_mask, diff_gez, diff_lez; 11 | __m128i sign, sign_notvt; 12 | 13 | #ifdef INTENSE_DEBUG 14 | for (unsigned i = 0; i < 8; i++) 15 | fprintf(stderr, "VS[%d] = %d\n", i, reinterpret_cast(&vs)[i]); 16 | 17 | for (unsigned i = 0; i < 8; i++) 18 | fprintf(stderr, "VT[%d] = %d\n", i, reinterpret_cast(&vt)[i]); 19 | #endif 20 | 21 | // sign = (vs ^ vt) < 0 22 | sign = _mm_xor_si128(vs, vt); 23 | sign = _mm_srai_epi16(sign, 15); 24 | 25 | // Compute le 26 | diff_lez = _mm_and_si128(vs, sign); 27 | diff_lez = _mm_add_epi16(diff_lez, vt); 28 | *le = _mm_srai_epi16(diff_lez, 15); 29 | 30 | // Compute ge 31 | diff_gez = _mm_or_si128(vs, sign); 32 | diff_gez = _mm_min_epi16(diff_gez, vt); 33 | *ge = _mm_cmpeq_epi16(diff_gez, vt); 34 | 35 | // sign_notvt = sn ? ~vt : vt 36 | sign_notvt = _mm_xor_si128(vt, sign); 37 | 38 | // Compute result: 39 | #ifdef __SSE4_1__ 40 | diff_sel_mask = _mm_blendv_epi8(*ge, *le, sign); 41 | return _mm_blendv_epi8(vs, sign_notvt, diff_sel_mask); 42 | #else 43 | diff_sel_mask = _mm_sub_epi16(*le, *ge); 44 | diff_sel_mask = _mm_and_si128(diff_sel_mask, sign); 45 | diff_sel_mask = _mm_add_epi16(diff_sel_mask, *ge); 46 | 47 | zero = _mm_sub_epi16(sign_notvt, vs); 48 | zero = _mm_and_si128(zero, diff_sel_mask); 49 | return _mm_add_epi16(zero, vs); 50 | #endif 51 | } 52 | -------------------------------------------------------------------------------- /arch/simd/rsp/vdivh.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vrcp.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | inline __m128i rsp_vdivh(RSP::CPUState *rsp, unsigned src, unsigned e, unsigned dest, unsigned de) 9 | { 10 | 11 | // Get the element from VT. 12 | rsp->cp2.div_in = rsp->cp2.regs[src].e[e & 0x7]; 13 | 14 | // Write out the upper part of the result. 15 | rsp->cp2.regs[dest].e[de & 0x7] = rsp->cp2.div_out; 16 | return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[dest].e); 17 | } 18 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmac.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmacf.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | template 9 | static inline __m128i rsp_vmacf_vmacu(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 10 | __m128i *acc_hi) 11 | { 12 | __m128i overflow_hi_mask, overflow_md_mask; 13 | __m128i lo, md, hi, carry, overflow_mask; 14 | 15 | // Get the product and shift it over 16 | // being sure to save the carries. 17 | lo = _mm_mullo_epi16(vs, vt); 18 | hi = _mm_mulhi_epi16(vs, vt); 19 | 20 | md = _mm_slli_epi16(hi, 1); 21 | carry = _mm_srli_epi16(lo, 15); 22 | hi = _mm_srai_epi16(hi, 15); 23 | md = _mm_or_si128(md, carry); 24 | lo = _mm_slli_epi16(lo, 1); 25 | 26 | // Tricky part: start accumulating everything. 27 | // Get/keep the carry as we'll add it in later. 28 | overflow_mask = _mm_adds_epu16(*acc_lo, lo); 29 | *acc_lo = _mm_add_epi16(*acc_lo, lo); 30 | 31 | overflow_mask = _mm_cmpeq_epi16(*acc_lo, overflow_mask); 32 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 33 | 34 | // Add in the carry. If the middle portion is 35 | // already 0xFFFF and we have a carry, we have 36 | // to carry the all the way up to hi. 37 | md = _mm_sub_epi16(md, overflow_mask); 38 | carry = _mm_cmpeq_epi16(md, zero); 39 | carry = _mm_and_si128(carry, overflow_mask); 40 | hi = _mm_sub_epi16(hi, carry); 41 | 42 | // Accumulate the middle portion. 43 | overflow_mask = _mm_adds_epu16(*acc_md, md); 44 | *acc_md = _mm_add_epi16(*acc_md, md); 45 | 46 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 47 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 48 | 49 | // Finish up the accumulation of the... accumulator. 50 | *acc_hi = _mm_add_epi16(*acc_hi, hi); 51 | *acc_hi = _mm_sub_epi16(*acc_hi, overflow_mask); 52 | 53 | // VMACU 54 | if (VMACU) 55 | { 56 | overflow_hi_mask = _mm_srai_epi16(*acc_hi, 15); 57 | overflow_md_mask = _mm_srai_epi16(*acc_md, 15); 58 | md = _mm_or_si128(overflow_md_mask, *acc_md); 59 | overflow_mask = _mm_cmpgt_epi16(*acc_hi, zero); 60 | md = _mm_andnot_si128(overflow_hi_mask, md); 61 | return _mm_or_si128(overflow_mask, md); 62 | } 63 | 64 | // VMACF 65 | else 66 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 67 | } 68 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmrg.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmrg.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vmrg(__m128i vs, __m128i vt, __m128i le) 9 | { 10 | #ifdef __SSE4_1__ 11 | return _mm_blendv_epi8(vt, vs, le); 12 | #else 13 | vs = _mm_and_si128(le, vs); 14 | vt = _mm_andnot_si128(le, vt); 15 | return _mm_or_si128(vs, vt); 16 | #endif 17 | } 18 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmudh.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmudh.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vmudh(__m128i vs, __m128i vt, __m128i *acc_md, __m128i *acc_hi) 9 | { 10 | *acc_md = _mm_mullo_epi16(vs, vt); 11 | *acc_hi = _mm_mulhi_epi16(vs, vt); 12 | 13 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 14 | } 15 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmul.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmul.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | // 9 | // TODO: CHECK ME. 10 | // 11 | 12 | template 13 | static inline __m128i rsp_vmulf_vmulu(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 14 | __m128i *acc_hi) 15 | { 16 | __m128i lo, hi, round, sign1, sign2, eq, neq, neg; 17 | 18 | lo = _mm_mullo_epi16(vs, vt); 19 | round = _mm_cmpeq_epi16(zero, zero); 20 | sign1 = _mm_srli_epi16(lo, 15); 21 | lo = _mm_add_epi16(lo, lo); 22 | round = _mm_slli_epi16(round, 15); 23 | hi = _mm_mulhi_epi16(vs, vt); 24 | sign2 = _mm_srli_epi16(lo, 15); 25 | *acc_lo = _mm_add_epi16(round, lo); 26 | sign1 = _mm_add_epi16(sign1, sign2); 27 | 28 | hi = _mm_slli_epi16(hi, 1); 29 | neq = eq = _mm_cmpeq_epi16(vs, vt); 30 | *acc_md = _mm_add_epi16(hi, sign1); 31 | 32 | neg = _mm_srai_epi16(*acc_md, 15); 33 | 34 | // VMULU 35 | if (VMULU) 36 | { 37 | *acc_hi = _mm_andnot_si128(eq, neg); 38 | hi = _mm_or_si128(*acc_md, neg); 39 | return _mm_andnot_si128(*acc_hi, hi); 40 | } 41 | 42 | // VMULF 43 | else 44 | { 45 | eq = _mm_and_si128(eq, neg); 46 | *acc_hi = _mm_andnot_si128(neq, neg); 47 | return _mm_add_epi16(*acc_md, eq); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmulh.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmulh.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | template 9 | static inline __m128i rsp_vmadh_vmudh(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 10 | __m128i *acc_hi) 11 | { 12 | __m128i lo, hi, overflow_mask; 13 | 14 | lo = _mm_mullo_epi16(vs, vt); 15 | hi = _mm_mulhi_epi16(vs, vt); 16 | 17 | // VMADH 18 | if (VMADH) 19 | { 20 | // Tricky part: start accumulate everything. 21 | // Get/keep the carry as we'll add it in later. 22 | overflow_mask = _mm_adds_epu16(*acc_md, lo); 23 | *acc_md = _mm_add_epi16(*acc_md, lo); 24 | 25 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 26 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 27 | 28 | hi = _mm_sub_epi16(hi, overflow_mask); 29 | *acc_hi = _mm_add_epi16(*acc_hi, hi); 30 | } 31 | 32 | // VMUDH 33 | else 34 | { 35 | *acc_lo = zero; 36 | *acc_md = lo; 37 | *acc_hi = hi; 38 | } 39 | 40 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 41 | } 42 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmull.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmadl.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | template 9 | static inline __m128i rsp_vmadl_vmudl(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 10 | __m128i *acc_hi) 11 | { 12 | __m128i hi, overflow_mask; 13 | 14 | hi = _mm_mulhi_epu16(vs, vt); 15 | 16 | // VMADL 17 | if (VMADL) 18 | { 19 | 20 | // Tricky part: start accumulate everything. 21 | // Get/keep the carry as we'll add it in later. 22 | overflow_mask = _mm_adds_epu16(*acc_lo, hi); 23 | *acc_lo = _mm_add_epi16(*acc_lo, hi); 24 | 25 | overflow_mask = _mm_cmpeq_epi16(*acc_lo, overflow_mask); 26 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 27 | hi = _mm_sub_epi16(zero, overflow_mask); 28 | 29 | // Check for overflow of the upper sum. 30 | // 31 | // TODO: Since hi can only be {0,1}, we should 32 | // be able to generalize this for performance. 33 | overflow_mask = _mm_adds_epu16(*acc_md, hi); 34 | *acc_md = _mm_add_epi16(*acc_md, hi); 35 | 36 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 37 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 38 | 39 | // Finish up the accumulation of the... accumulator. 40 | // Since the product was unsigned, only worry about 41 | // positive overflow (i.e.: borrowing not possible). 42 | *acc_hi = _mm_sub_epi16(*acc_hi, overflow_mask); 43 | 44 | return rsp_uclamp_acc(*acc_lo, *acc_md, *acc_hi, zero); 45 | } 46 | 47 | // VMUDL 48 | else 49 | { 50 | *acc_lo = hi; 51 | *acc_md = zero; 52 | *acc_hi = zero; 53 | 54 | return hi; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmulm.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmulm.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | template 9 | static inline __m128i rsp_vmadm_vmudm(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 10 | __m128i *acc_hi) 11 | { 12 | __m128i lo, hi, sign, overflow_mask; 13 | 14 | lo = _mm_mullo_epi16(vs, vt); 15 | hi = _mm_mulhi_epu16(vs, vt); 16 | 17 | // What we're really want to do is unsigned vs * signed vt. 18 | // However, we have no such instructions to do so. 19 | // 20 | // There's a trick to "fix" an unsigned product, though: 21 | // If vt was negative, take the upper 16-bits of the product 22 | // and subtract vs. 23 | sign = _mm_srai_epi16(vs, 15); 24 | vt = _mm_and_si128(vt, sign); 25 | hi = _mm_sub_epi16(hi, vt); 26 | 27 | // VMADM 28 | if (VMADM) 29 | { 30 | // Tricky part: start accumulate everything. 31 | // Get/keep the carry as we'll add it in later. 32 | overflow_mask = _mm_adds_epu16(*acc_lo, lo); 33 | *acc_lo = _mm_add_epi16(*acc_lo, lo); 34 | 35 | overflow_mask = _mm_cmpeq_epi16(*acc_lo, overflow_mask); 36 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 37 | 38 | // This is REALLY clever. Since the product results from 39 | // two 16-bit components, one positive and one negative, 40 | // we don't have to worry about carrying the 1 (we can 41 | // only borrow) past 32-bits. So we can just add it here. 42 | hi = _mm_sub_epi16(hi, overflow_mask); 43 | 44 | // Check for overflow of the upper sum. 45 | overflow_mask = _mm_adds_epu16(*acc_md, hi); 46 | *acc_md = _mm_add_epi16(*acc_md, hi); 47 | 48 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 49 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 50 | 51 | // Finish up the accumulation of the... accumulator. 52 | *acc_hi = _mm_add_epi16(*acc_hi, _mm_srai_epi16(hi, 15)); 53 | *acc_hi = _mm_sub_epi16(*acc_hi, overflow_mask); 54 | 55 | return rsp_sclamp_acc_tomd(*acc_md, *acc_hi); 56 | } 57 | 58 | // VMUDM 59 | else 60 | { 61 | *acc_lo = lo; 62 | *acc_md = hi; 63 | *acc_hi = _mm_srai_epi16(hi, 15); 64 | 65 | return hi; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /arch/simd/rsp/vmuln.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vmuln.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | template 9 | static inline __m128i rsp_vmadn_vmudn(__m128i vs, __m128i vt, __m128i zero, __m128i *acc_lo, __m128i *acc_md, 10 | __m128i *acc_hi) 11 | { 12 | __m128i lo, hi, sign, overflow_mask; 13 | 14 | #ifdef INTENSE_DEBUG 15 | if (VMADN) 16 | { 17 | for (unsigned i = 0; i < 8; i++) 18 | fprintf(stderr, "ACC LO[%u] = %d\n", i, reinterpret_cast(acc_lo)[i]); 19 | for (unsigned i = 0; i < 8; i++) 20 | fprintf(stderr, "ACC MD[%u] = %d\n", i, reinterpret_cast(acc_md)[i]); 21 | for (unsigned i = 0; i < 8; i++) 22 | fprintf(stderr, "ACC HI[%u] = %d\n", i, reinterpret_cast(acc_hi)[i]); 23 | for (unsigned i = 0; i < 8; i++) 24 | fprintf(stderr, "VS[%u] = %d\n", i, reinterpret_cast(&vs)[i]); 25 | for (unsigned i = 0; i < 8; i++) 26 | fprintf(stderr, "VT[%u] = %d\n", i, reinterpret_cast(&vt)[i]); 27 | } 28 | #endif 29 | 30 | lo = _mm_mullo_epi16(vs, vt); 31 | hi = _mm_mulhi_epu16(vs, vt); 32 | 33 | // What we're really want to do is unsigned vs * signed vt. 34 | // However, we have no such instructions to do so. 35 | // 36 | // There's a trick to "fix" an unsigned product, though: 37 | // If vt was negative, take the upper 16-bits of the product 38 | // and subtract vs. 39 | sign = _mm_srai_epi16(vt, 15); 40 | vs = _mm_and_si128(vs, sign); 41 | hi = _mm_sub_epi16(hi, vs); 42 | 43 | // VMADN 44 | if (VMADN) 45 | { 46 | // Tricky part: start accumulate everything. 47 | // Get/keep the carry as we'll add it in later. 48 | overflow_mask = _mm_adds_epu16(*acc_lo, lo); 49 | *acc_lo = _mm_add_epi16(*acc_lo, lo); 50 | 51 | overflow_mask = _mm_cmpeq_epi16(*acc_lo, overflow_mask); 52 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 53 | 54 | // This is REALLY clever. Since the product results from 55 | // two 16-bit components, one positive and one negative, 56 | // we don't have to worry about carrying the 1 (we can 57 | // only borrow) past 32-bits. So we can just add it here. 58 | hi = _mm_sub_epi16(hi, overflow_mask); 59 | 60 | // Check for overflow of the upper sum. 61 | overflow_mask = _mm_adds_epu16(*acc_md, hi); 62 | *acc_md = _mm_add_epi16(*acc_md, hi); 63 | 64 | overflow_mask = _mm_cmpeq_epi16(*acc_md, overflow_mask); 65 | overflow_mask = _mm_cmpeq_epi16(overflow_mask, zero); 66 | 67 | // Finish up the accumulation of the... accumulator. 68 | *acc_hi = _mm_add_epi16(*acc_hi, _mm_srai_epi16(hi, 15)); 69 | *acc_hi = _mm_sub_epi16(*acc_hi, overflow_mask); 70 | #ifdef INTENSE_DEBUG 71 | auto ret = rsp_uclamp_acc(*acc_lo, *acc_md, *acc_hi, zero); 72 | for (unsigned i = 0; i < 8; i++) 73 | fprintf(stderr, "VD[%u] = %d\n", i, reinterpret_cast(&ret)[i]); 74 | return ret; 75 | #else 76 | return rsp_uclamp_acc(*acc_lo, *acc_md, *acc_hi, zero); 77 | #endif 78 | } 79 | 80 | // VMUDN 81 | else 82 | { 83 | *acc_lo = lo; 84 | *acc_md = hi; 85 | *acc_hi = _mm_srai_epi16(hi, 15); 86 | 87 | return lo; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /arch/simd/rsp/vor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vor(__m128i vs, __m128i vt) 9 | { 10 | return _mm_or_si128(vs, vt); 11 | } 12 | 13 | static inline __m128i rsp_vnor(__m128i vs, __m128i vt) 14 | { 15 | __m128i vd = _mm_or_si128(vs, vt); 16 | return _mm_xor_si128(vd, _mm_set1_epi32(0xffffffffu)); 17 | } 18 | -------------------------------------------------------------------------------- /arch/simd/rsp/vrcpsq.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vrcpsq.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "../../../rsp/reciprocal.h" 9 | 10 | template 11 | inline __m128i rsp_vrcp_vrsq(RSP::CPUState *rsp, int dp, unsigned src, unsigned e, unsigned dest, unsigned de) 12 | { 13 | uint32_t dp_input, sp_input; 14 | int32_t input, result; 15 | 16 | int16_t vt; 17 | 18 | int32_t input_mask, data; 19 | unsigned shift, idx; 20 | 21 | // Get the element from VT. 22 | vt = rsp->cp2.regs[src].e[e & 0x7]; 23 | 24 | dp_input = ((uint32_t)rsp->cp2.div_in << 16) | (uint16_t)vt; 25 | sp_input = vt; 26 | 27 | input = (dp) ? dp_input : sp_input; 28 | input_mask = input >> 31; 29 | data = input ^ input_mask; 30 | 31 | if (input > -32768) 32 | data -= input_mask; 33 | 34 | // Handle edge cases. 35 | if (data == 0) 36 | result = 0x7fffFFFFU; 37 | 38 | else if (input == -32768) 39 | result = 0xffff0000U; 40 | 41 | // Main case: compute the reciprocal. 42 | else 43 | { 44 | 45 | // TODO: Clean this up. 46 | #ifdef _MSC_VER 47 | unsigned long bsf_index; 48 | _BitScanReverse(&bsf_index, data); 49 | shift = 31 - bsf_index; 50 | #else 51 | shift = __builtin_clz(data); 52 | #endif 53 | 54 | // VRSQ 55 | if (VRSQ) 56 | { 57 | idx = (((unsigned long long)data << shift) & 0x7FC00000U) >> 22; 58 | idx = ((idx | 0x200) & 0x3FE) | (shift % 2); 59 | result = rsp_reciprocal_rom[idx]; 60 | 61 | result = ((0x10000 | result) << 14) >> ((31 - shift) >> 1); 62 | } 63 | 64 | // VRCP 65 | else 66 | { 67 | idx = (((unsigned long long)data << shift) & 0x7FC00000U) >> 22; 68 | result = rsp_reciprocal_rom[idx]; 69 | 70 | result = ((0x10000 | result) << 14) >> (31 - shift); 71 | } 72 | 73 | result = result ^ input_mask; 74 | } 75 | 76 | // Write out the results. 77 | rsp->cp2.div_out = result >> 16; 78 | rsp->cp2.regs[dest].e[de & 0x7] = result; 79 | 80 | return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[dest].e); 81 | } 82 | -------------------------------------------------------------------------------- /arch/simd/rsp/vrsq.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vrsq.c 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | #include "../../../rsp/reciprocal.h" 9 | #include 10 | 11 | // Mask table for vrsq(LH) functions. 12 | alignas(16) static const uint16_t vrsq_mask_table[8][8] = { 13 | { 0xffff, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0xffff, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0xffff, 0, 0, 0, 0, 0 }, 14 | { 0, 0, 0, 0xffff, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0xffff, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0xffff, 0, 0 }, 15 | { 0, 0, 0, 0, 0, 0, 0xffff, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0xffff } 16 | }; 17 | 18 | inline __m128i rsp_vrsq(RSP::CPUState *rsp, int dp, unsigned src, unsigned e, unsigned dest, unsigned de) 19 | { 20 | uint32_t dp_input, sp_input; 21 | int32_t input, result; 22 | int16_t vt; 23 | 24 | int32_t input_mask, data; 25 | unsigned shift, idx; 26 | 27 | // Get the element from VT. 28 | vt = rsp->cp2.regs[src].e[e & 0x7]; 29 | 30 | dp_input = ((uint32_t)rsp->cp2.div_in << 16) | (uint16_t)vt; 31 | sp_input = vt; 32 | 33 | input = (dp) ? dp_input : sp_input; 34 | input_mask = input >> 31; 35 | data = input ^ input_mask; 36 | 37 | if (input > -32768) 38 | data -= input_mask; 39 | 40 | // Handle edge cases. 41 | if (data == 0) 42 | result = 0x7fffFFFFU; 43 | 44 | else if (input == -32768) 45 | result = 0xffff0000U; 46 | 47 | // Main case: compute the reciprocal. 48 | else 49 | { 50 | 51 | //TODO: Clean this up. 52 | #ifdef _MSC_VER 53 | unsigned long bsf_index; 54 | _BitScanReverse(&bsf_index, data); 55 | shift = 31 - bsf_index; 56 | #else 57 | shift = __builtin_clz(data); 58 | #endif 59 | 60 | idx = (((unsigned long long)data << shift) & 0x7FC00000U) >> 22; 61 | idx = ((idx | 0x200) & 0x3FE) | (shift % 2); 62 | result = rsp_reciprocal_rom[idx]; 63 | 64 | result = ((0x10000 | result) << 14) >> ((31 - shift) >> 1); 65 | result = result ^ input_mask; 66 | } 67 | 68 | // Write out the results. 69 | rsp->cp2.div_out = result >> 16; 70 | rsp->cp2.regs[dest].e[de & 0x7] = result; 71 | 72 | return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[dest].e); 73 | } 74 | 75 | inline __m128i rsp_vrsqh(RSP::CPUState *rsp, unsigned src, unsigned e, unsigned dest, unsigned de) 76 | { 77 | __m128i vd, vd_mask, b_result; 78 | 79 | int16_t elements[8]; 80 | 81 | // Get the element from VT. 82 | memcpy(elements, rsp->cp2.regs + src, sizeof(elements)); 83 | rsp->cp2.div_in = elements[e]; 84 | 85 | // Write out the upper part of the result. 86 | vd_mask = _mm_load_si128((__m128i *)vrsq_mask_table[de]); 87 | vd = _mm_load_si128((__m128i *)(rsp->cp2.regs + dest)); 88 | vd = _mm_andnot_si128(vd_mask, vd); 89 | 90 | b_result = _mm_set1_epi16(rsp->cp2.div_out); 91 | b_result = _mm_and_si128(vd_mask, b_result); 92 | return _mm_or_si128(b_result, vd); 93 | } 94 | -------------------------------------------------------------------------------- /arch/simd/rsp/vsub.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vsub.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vsub(__m128i vs, __m128i vt, __m128i carry, __m128i *acc_lo) 9 | { 10 | __m128i unsat_diff, sat_diff, overflow, vd; 11 | 12 | // acc_lo uses saturated arithmetic. 13 | unsat_diff = _mm_sub_epi16(vt, carry); 14 | sat_diff = _mm_subs_epi16(vt, carry); 15 | 16 | *acc_lo = _mm_sub_epi16(vs, unsat_diff); 17 | vd = _mm_subs_epi16(vs, sat_diff); 18 | 19 | // VD is the signed diff of the two sources and the carry. Since we 20 | // have to saturate the diff of all three, we have to be clever. 21 | overflow = _mm_cmpgt_epi16(sat_diff, unsat_diff); 22 | return _mm_adds_epi16(vd, overflow); 23 | } 24 | -------------------------------------------------------------------------------- /arch/simd/rsp/vsubc.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vsubc.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vsubc(__m128i vs, __m128i vt, __m128i zero, __m128i *eq, __m128i *sn) 9 | { 10 | __m128i equal, sat_udiff, sat_udiff_zero; 11 | 12 | sat_udiff = _mm_subs_epu16(vs, vt); 13 | equal = _mm_cmpeq_epi16(vs, vt); 14 | sat_udiff_zero = _mm_cmpeq_epi16(sat_udiff, zero); 15 | 16 | *eq = _mm_cmpeq_epi16(equal, zero); 17 | *sn = _mm_andnot_si128(equal, sat_udiff_zero); 18 | 19 | return _mm_sub_epi16(vs, vt); 20 | } 21 | -------------------------------------------------------------------------------- /arch/simd/rsp/vxor.h: -------------------------------------------------------------------------------- 1 | // 2 | // arch/x86_64/rsp/vxor.h 3 | // 4 | // This file is subject to the terms and conditions defined in 5 | // 'LICENSE', which is part of this source code package. 6 | // 7 | 8 | static inline __m128i rsp_vxor(__m128i vs, __m128i vt) 9 | { 10 | return _mm_xor_si128(vs, vt); 11 | } 12 | 13 | static inline __m128i rsp_vnxor(__m128i vs, __m128i vt) 14 | { 15 | __m128i vd = _mm_xor_si128(vs, vt); 16 | return _mm_xor_si128(vd, _mm_set1_epi32(0xffffffffu)); 17 | } 18 | -------------------------------------------------------------------------------- /build_android_aarch64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $ANDROID_HOME ]; then 4 | echo "Please define ANDROID_HOME environment variable to where Android SDK is installed, usually ~/Android/Sdk." 5 | exit 1 6 | fi 7 | 8 | mkdir -p build-android-aarch64 9 | cd build-android-aarch64 10 | cmake .. -DCMAKE_TOOLCHAIN_FILE="$ANDROID_HOME/ndk-bundle/build/cmake/android.toolchain.cmake" \ 11 | -DANDROID_ABI=arm64-v8a \ 12 | -DCMAKE_BUILD_TYPE=Release \ 13 | -DANDROID_PLATFORM=android-26 \ 14 | -DPARALLEL_RSP_DEBUG_JIT=OFF 15 | cmake --build . --parallel 16 | cd .. 17 | -------------------------------------------------------------------------------- /build_native.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p build-native 4 | cd build-native 5 | cmake .. -DCMAKE_BUILD_TYPE=Release -DPARALLEL_RSP_DEBUG_JIT=OFF 6 | cmake --build . --parallel 7 | cd .. 8 | -------------------------------------------------------------------------------- /compare_test_results.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./build_android_aarch64.sh || exit 1 4 | cd build-android-aarch64 5 | echo "Running Android test suite ..." 6 | ctest --no-label-summary --verbose >android-aarch64.log || exit 1 7 | cd .. 8 | 9 | ./build_native.sh || exit 1 10 | cd build-native 11 | echo "Running native test suite ..." 12 | ctest --no-label-summary --verbose >native.log || exit 1 13 | cd .. 14 | 15 | echo "Comparing output ..." 16 | echo "==============================" 17 | diff -Naur build-native/native.log build-android-aarch64/android-aarch64.log 18 | echo "==============================" 19 | -------------------------------------------------------------------------------- /cpu_state.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RSP_CPU_STATE_HPP 2 | #define RSP_CPU_STATE_HPP 3 | 4 | 5 | #endif -------------------------------------------------------------------------------- /debug-toolchain/Makefile: -------------------------------------------------------------------------------- 1 | RSP_TEST = main 2 | 3 | PROGRAM = $(RSP_TEST) 4 | MIPS_OBJ = $(RSP_TEST).o 5 | 6 | include Makefile.mips 7 | -------------------------------------------------------------------------------- /debug-toolchain/Makefile.mips: -------------------------------------------------------------------------------- 1 | #### 2 | ## Basic Makefile for RSP-MIPS 3 | ## 4 | ###### 5 | 6 | TARGET_ELF = $(PROGRAM).elf 7 | TARGET_BIN = $(PROGRAM).bin 8 | TARGET_GLOBAL_BIN = $(PROGRAM).global.bin 9 | MIPS_LD_SCRIPT = rsp-mips.ld 10 | 11 | MIPS_OBJCOPY = mipsel-linux-gnu-objcopy 12 | MIPS_CC = mipsel-linux-gnu-gcc 13 | MIPS_AS = mipsel-linux-gnu-as 14 | MIPS_LD = mipsel-linux-gnu-ld 15 | CRT_OBJ = start.o rsp-mips.o 16 | 17 | all: $(TARGET_BIN) $(TARGET_GLOBAL_BIN) 18 | 19 | crt-obj: $(CRT_OBJ) 20 | 21 | $(TARGET_BIN): $(TARGET_ELF) 22 | $(MIPS_OBJCOPY) -j .text $< $(TARGET_BIN) -O binary 23 | 24 | $(TARGET_GLOBAL_BIN): $(TARGET_ELF) 25 | $(MIPS_OBJCOPY) -j .data $< $(TARGET_GLOBAL_BIN) -O binary 26 | 27 | $(TARGET_ELF): $(MIPS_OBJ) $(CRT_OBJ) 28 | $(MIPS_LD) -T $(MIPS_LD_SCRIPT) -o $@ $(CRT_OBJ) $(MIPS_OBJ) -EB 29 | 30 | %.o: %.s 31 | $(MIPS_AS) -o $@ $< -EB -mabi=eabi -march=mips1 32 | 33 | %.o: %.c rsp-mips.h 34 | $(MIPS_CC) -c -o $@ $< -Os -EB -march=mips1 -mabi=eabi -mno-abicalls -std=gnu99 -nostdlib 35 | 36 | clean: 37 | rm -f $(MIPS_OBJ) $(CRT_OBJ) $(TARGET_ELF) $(TARGET_HEX) $(TARGET_GLOBAL_HEX) $(TARGET_BIN) $(TARGET_GLOBAL_BIN) 38 | 39 | .PHONY: all clean tools 40 | 41 | -------------------------------------------------------------------------------- /debug-toolchain/add.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 40 5 | li $t1, -20 6 | add $t2, $t0, $t1 7 | addu $t3, $t0, $t1 8 | 9 | li $t0, -5 10 | li $t1, -4 11 | add $t2, $t0, $t1 12 | addu $t3, $t0, $t1 13 | break 14 | -------------------------------------------------------------------------------- /debug-toolchain/addi.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 17 5 | addi $t0, $a0, -8 6 | addi $t1, $a0, 8 7 | addiu $t2, $a0, -8 8 | addiu $t3, $a0, 8 9 | break 10 | -------------------------------------------------------------------------------- /debug-toolchain/and.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 17 5 | li $t1, 5 6 | and $t2, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/andi.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, -1 5 | andi $t0, $a0, 50000 6 | break 7 | -------------------------------------------------------------------------------- /debug-toolchain/beq-impossible-delay-slot-both-taken.s: -------------------------------------------------------------------------------- 1 | # This works on the Lightning JIT, but hangs the reference. 2 | 3 | .text 4 | .set noreorder 5 | .global main 6 | main: 7 | li $t0, 1 8 | li $t1, 1 9 | li $t2, 2 10 | li $t3, 0 11 | beq $t0, $t1, taken0 # This will be taken. 12 | beq $t0, $t1, taken1 # This will also be taken. 13 | li $t3, 3 # This will not be executed. 14 | 15 | taken0: 16 | li $t6, 5 # This will be executed, the second branch then kicks in and runs taken1 path. 17 | break 18 | taken1: 19 | li $t4, 4 # This will be executed. 20 | break 21 | -------------------------------------------------------------------------------- /debug-toolchain/beq-impossible-delay-slot-first-taken.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | li $t1, 1 7 | li $t2, 2 8 | li $t3, 0 9 | beq $t0, $t1, taken0 # This will be taken. 10 | beq $t0, $t2, taken1 # Will not be taken. 11 | li $t3, 3 12 | 13 | taken0: 14 | li $t4, 5 15 | break 16 | taken1: 17 | li $t4, 4 18 | break 19 | -------------------------------------------------------------------------------- /debug-toolchain/beq-impossible-delay-slot-second-taken.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | li $t1, 1 7 | li $t2, 2 8 | li $t3, 0 9 | beq $t0, $t2, taken0 # This will not be taken, should be ignored. 10 | beq $t0, $t1, taken1 # This will be taken. 11 | li $t3, 3 12 | 13 | taken0: 14 | li $t4, 5 15 | break 16 | taken1: 17 | li $t4, 4 18 | break 19 | -------------------------------------------------------------------------------- /debug-toolchain/bgez.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, -1 6 | bgez $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | bgez $t0, taken1 # This will be taken. 11 | li $t2, 20 12 | 13 | li $t0, 1 14 | bgez $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/bgezal.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, -1 6 | bgezal $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | bgezal $t0, taken1 # This will be taken. 11 | li $t2, 20 12 | 13 | li $t0, 1 14 | bgezal $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/bgtz.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, -1 6 | bgtz $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | bgtz $t0, taken1 # This will not be taken. 11 | li $t2, 20 12 | 13 | li $t0, 1 14 | bgtz $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/blez.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | blez $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | blez $t0, taken1 # This will be taken. 11 | li $t2, 20 12 | 13 | li $t0, 0 14 | blez $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/bltz.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | bltz $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | bltz $t0, taken1 # This will not be taken. 11 | li $t2, 20 12 | 13 | li $t0, -1 14 | bltz $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/bltzal.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | bltzal $t0, taken1 # This will not be taken. 7 | li $t2, 10 8 | 9 | li $t0, 0 10 | bltzal $t0, taken1 # This will not be taken. 11 | li $t2, 20 12 | 13 | li $t0, -1 14 | bltzal $t0, taken1 # This will be taken. 15 | li $t2, 30 16 | 17 | taken0: 18 | li $t4, 5 19 | break 20 | taken1: 21 | li $t4, 4 22 | break 23 | -------------------------------------------------------------------------------- /debug-toolchain/bne.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | li $t1, 1 7 | li $t2, 2 8 | li $t3, 0 9 | bne $t0, $t1, taken0 # This will not be taken. 10 | nop 11 | 12 | bne $t0, $t2, taken1 # Will be taken. 13 | li $t3, 3 14 | 15 | taken0: 16 | li $t4, 5 17 | break 18 | taken1: 19 | li $t4, 4 20 | break 21 | -------------------------------------------------------------------------------- /debug-toolchain/bug-shl-into-branch.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t1, ((0x50000000) << 5) & 0xffffffff 5 | li $t0, 0x50000000 6 | sll $t0, $t0, 5 7 | bne $t0, $t1, error 8 | nop 9 | 10 | li $t2, 1 11 | break 12 | 13 | error: 14 | li $t2, 2 15 | break 16 | -------------------------------------------------------------------------------- /debug-toolchain/cop0.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 100 6 | mtc0 $t0, $1 7 | bgez $t0, bar 8 | mfc0 $t1, $1 9 | li $t1, 200 # Should not execute. 10 | break 11 | 12 | bar: 13 | li $t2, 400 14 | break 15 | -------------------------------------------------------------------------------- /debug-toolchain/cop2-basic.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 10 6 | li $t2, 10 7 | nop 8 | .word (0x12 << 26) | (4 << 21) | (2 << 11) | (8 << 16) | (4 << 7) 9 | .word (0x12 << 26) | (0 << 21) | (2 << 11) | (9 << 16) | (4 << 7) 10 | #mtc2 $t0, $2, 4 11 | #mfc2 $t1, $2, 4 12 | 13 | ctc2 $t2, $2 14 | cfc2 $t3, $2 15 | 16 | break 17 | -------------------------------------------------------------------------------- /debug-toolchain/cop2-ls.s: -------------------------------------------------------------------------------- 1 | .data 2 | buffer: 3 | .hword 10, 20, 30, 40, 50, 60, 70, 80 4 | .hword 20, 30, 40, 50, 60, 70, 80, 90 5 | 6 | .text 7 | .set noreorder 8 | .global main 9 | main: 10 | la $t0, buffer 11 | # lqv 2, 0, 1(t0) 12 | .word (0x32 << 26) | (4 << 11) | (2 << 16) | (0 << 7) | (1 << 0) | (8 << 21) 13 | # sqv 2, 0, 2(t0) 14 | .word (0x3a << 26) | (4 << 11) | (2 << 16) | (0 << 7) | (2 << 0) | (8 << 21) 15 | break 16 | -------------------------------------------------------------------------------- /debug-toolchain/cop2-vector.s: -------------------------------------------------------------------------------- 1 | .data 2 | buffer: 3 | .hword 10, 20, 30, 40, 50, 60, 70, 80 4 | .hword 20, 30, 40, 50, 60, 70, 80, 90 5 | 6 | .text 7 | .set noreorder 8 | .global main 9 | main: 10 | la $t0, buffer 11 | # lqv 2, 0, 0(t0) 12 | .word (0x32 << 26) | (4 << 11) | (2 << 16) | (0 << 7) | (0 << 0) | (8 << 21) 13 | # lqv 3, 0, 1(t0) 14 | .word (0x32 << 26) | (4 << 11) | (3 << 16) | (0 << 7) | (1 << 0) | (8 << 21) 15 | 16 | .word (0x25 << 25) | (4 << 6) | (2 << 11) | (3 << 16) | (17 << 0) | (0 << 21) 17 | # vsub v4, v2, v3, 0 18 | break 19 | -------------------------------------------------------------------------------- /debug-toolchain/delay-slot-before-break.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | blez $t0, foo 7 | break 8 | 9 | nop 10 | nop 11 | nop 12 | nop 13 | 14 | foo: 15 | break 16 | -------------------------------------------------------------------------------- /debug-toolchain/delay-slot-before-new-block-illegal.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | .align 10 5 | main: 6 | li $t0, 1 7 | .rept 126 8 | nop 9 | .endr 10 | bgtz $t0, foobar 11 | # New block begins here, 12 | j foobar2 13 | li $t2, 2 # This should not execute 14 | 15 | foobar: 16 | li $t3, 3 # This should execute, then we move to foobar2 17 | break 18 | 19 | foobar2: 20 | li $t4, 4 # This executes. 21 | break 22 | -------------------------------------------------------------------------------- /debug-toolchain/delay-slot-before-new-block-not-taken.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | .align 10 5 | main: 6 | li $t0, 0 7 | .rept 126 8 | nop 9 | .endr 10 | bgtz $t0, foobar 11 | # New block begins here, 12 | # last instruction will be bgtz which needs to promote its delay slot 13 | # into a new block. 14 | # First instruction of any block have to handle potential latent delay slots like these. 15 | li $t1, 1 16 | li $t2, 2 # This should execute 17 | 18 | foobar: 19 | break 20 | -------------------------------------------------------------------------------- /debug-toolchain/delay-slot-before-new-block.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | .align 10 5 | main: 6 | li $t0, 1 7 | .rept 126 8 | nop 9 | .endr 10 | bgtz $t0, foobar 11 | # New block begins here, 12 | # last instruction will be bgtz which needs to promote its delay slot 13 | # into a new block. 14 | # First instruction of any block have to handle potential latent delay slots like these. 15 | li $t1, 1 16 | li $t2, 2 # This should not execute 17 | 18 | foobar: 19 | break 20 | -------------------------------------------------------------------------------- /debug-toolchain/j.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | j indelay 6 | nop 7 | 8 | j die # Test to make sure this becomes a conditional branch. 9 | 10 | indelay: 11 | j notdie 12 | li $t0, 1 13 | 14 | die: 15 | li $t0, 0x10000 16 | 17 | notdie: 18 | li $t1, 2 19 | break 20 | 21 | -------------------------------------------------------------------------------- /debug-toolchain/jal-into-indirect-delay-slot.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | li $t0, 1 6 | bgtz $0, dummy 7 | jal callsite 8 | li $t5, 10 9 | 10 | jr $s5 11 | callsite: 12 | lw $t2, 184($0) 13 | li $t1, 10 14 | break 15 | 16 | dummy: 17 | nop 18 | break 19 | 20 | -------------------------------------------------------------------------------- /debug-toolchain/jal.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | jal indelay 6 | nop 7 | 8 | jal die # Test to make sure this becomes a conditional branch. 9 | 10 | indelay: 11 | jal notdie 12 | move $t2, $ra 13 | li $t0, 1 14 | 15 | die: 16 | li $t0, 0x10000 17 | 18 | notdie: 19 | li $t1, 2 20 | break 21 | 22 | -------------------------------------------------------------------------------- /debug-toolchain/jalr.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | la $t5, notdie 6 | la $ra, indelay 7 | jalr $a0, $ra 8 | move $ra, $a0 9 | 10 | j die # Test to make sure this becomes a conditional branch. 11 | 12 | indelay: 13 | jalr $a0, $t5 14 | move $t0, $a0 15 | 16 | die: 17 | li $t0, 0x10000 18 | 19 | notdie: 20 | li $t1, 2 21 | break 22 | 23 | -------------------------------------------------------------------------------- /debug-toolchain/jr.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | la $t5, notdie 6 | la $ra, indelay 7 | jr $ra 8 | nop 9 | 10 | j die # Test to make sure this becomes a conditional branch. 11 | 12 | indelay: 13 | jr $t5 14 | li $t0, 1 15 | 16 | die: 17 | li $t0, 0x10000 18 | 19 | notdie: 20 | li $t1, 2 21 | break 22 | 23 | -------------------------------------------------------------------------------- /debug-toolchain/lb.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0 3 | foobar: 4 | .byte 0x72, 0x91 5 | 6 | .text 7 | .global main 8 | main: 9 | la $t1, foobar 10 | lb $t0, 1($t1) 11 | break 12 | -------------------------------------------------------------------------------- /debug-toolchain/lbu.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0 3 | foobar: 4 | .byte 0x72, 0x91 5 | 6 | .text 7 | .global main 8 | main: 9 | la $t1, foobar 10 | lbu $t0, 1($t1) 11 | break 12 | -------------------------------------------------------------------------------- /debug-toolchain/lh-unaligned.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .byte 0 5 | .byte 0x92, 0x70 6 | 7 | .text 8 | .global main 9 | main: 10 | la $t1, foobar 11 | lh $t0, 1($t1) 12 | break 13 | -------------------------------------------------------------------------------- /debug-toolchain/lh.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .byte 0x92, 0x70 5 | 6 | .text 7 | .global main 8 | main: 9 | la $t1, foobar 10 | lh $t0, 0($t1) 11 | break 12 | -------------------------------------------------------------------------------- /debug-toolchain/lhu-unaligned.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .byte 0 5 | .byte 0x92, 0x70 6 | 7 | .text 8 | .global main 9 | main: 10 | la $t1, foobar 11 | lhu $t0, 1($t1) 12 | break 13 | -------------------------------------------------------------------------------- /debug-toolchain/lhu.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .byte 0x92, 0x70 5 | 6 | .text 7 | .global main 8 | main: 9 | la $t1, foobar 10 | lhu $t0, 0($t1) 11 | break 12 | -------------------------------------------------------------------------------- /debug-toolchain/lui.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | lui $t0, 50000 5 | break 6 | -------------------------------------------------------------------------------- /debug-toolchain/lw-unaligned-in-branch-delay.s: -------------------------------------------------------------------------------- 1 | .data 2 | foo: 3 | .byte 0 4 | .byte 0xaa, 0xbb, 0xcc, 0xdd 5 | 6 | .text 7 | .set noreorder 8 | .global main 9 | main: 10 | li $t0, 1 11 | la $t1, foo 12 | bgtz $t0, taken1 13 | lw $t1, 1($t1) 14 | 15 | taken0: 16 | li $t5, 100 17 | break 18 | 19 | taken1: 20 | break 21 | -------------------------------------------------------------------------------- /debug-toolchain/lw-unaligned.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .word 12345678 5 | .word 30 6 | 7 | .text 8 | .global main 9 | main: 10 | la $t1, foobar 11 | lw $t0, 0($t1) 12 | lw $t1, 1($t1) 13 | lw $t2, 2($t1) 14 | lw $t3, 3($t1) 15 | break 16 | -------------------------------------------------------------------------------- /debug-toolchain/lw.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0, 0, 0, 0 3 | foobar: 4 | .word 12345678 5 | .word 30 6 | 7 | .text 8 | .global main 9 | main: 10 | la $t1, foobar 11 | lw $t0, 4($t1) 12 | break 13 | -------------------------------------------------------------------------------- /debug-toolchain/main.c: -------------------------------------------------------------------------------- 1 | #include "rsp-mips.h" 2 | 3 | u8 data[4] = { 0x10, 0x20, 0x30, 0x40 }; 4 | 5 | __attribute__((noinline)) 6 | int load_byte(int i) 7 | { 8 | return data[i]; 9 | } 10 | 11 | int count = 3; 12 | 13 | int main(void) 14 | { 15 | int res = 0; 16 | for (int i = 0; i < 3; i++) 17 | { 18 | res += load_byte(i); 19 | } 20 | rsp_debug_break(res, res, res, res); 21 | } 22 | -------------------------------------------------------------------------------- /debug-toolchain/nor.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 17 5 | li $t1, 5 6 | nor $t2, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/or.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 8 5 | li $t1, 50 6 | or $t2, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/ori.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 500 5 | ori $t0, $a0, 50000 6 | break 7 | -------------------------------------------------------------------------------- /debug-toolchain/rsp-mips.h: -------------------------------------------------------------------------------- 1 | #ifndef __RSP_MIPS_H 2 | #define __RSP_MIPS_H 3 | 4 | typedef signed char s8; 5 | typedef unsigned char u8; 6 | typedef signed short s16; 7 | typedef unsigned short u16; 8 | typedef signed int s32; 9 | typedef unsigned int u32; 10 | typedef signed long long s64; 11 | typedef unsigned long long u64; 12 | typedef u32 size_t; 13 | 14 | void rsp_break(void); 15 | void rsp_debug_break(u32 a, u32 b, u32 c, u32 d); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /debug-toolchain/rsp-mips.ld: -------------------------------------------------------------------------------- 1 | SECTIONS { 2 | ENTRY(rsp_mips_start) 3 | . = 0x00400000; 4 | .text : { start.o (.text); * (.text*); } 5 | 6 | . = 0x00700000; 7 | .data : { * (.data); * (.rodata*); * (.sbss); * (.scommon); } 8 | .bss : { * (.bss); } 9 | } 10 | -------------------------------------------------------------------------------- /debug-toolchain/rsp-mips.s: -------------------------------------------------------------------------------- 1 | .text 2 | .section .text 3 | 4 | .global rsp_break 5 | .ent rsp_break 6 | .type rsp_break, @function 7 | rsp_break: 8 | break 9 | jr $ra 10 | .end rsp_break 11 | .size rsp_break, .-rsp_break 12 | 13 | .global rsp_debug_break 14 | .ent rsp_debug_break 15 | .type rsp_debug_break, @function 16 | rsp_debug_break: 17 | break 18 | jr $ra 19 | .end rsp_debug_break 20 | .size rsp_debug_break, .-rsp_debug_break 21 | -------------------------------------------------------------------------------- /debug-toolchain/sb.s: -------------------------------------------------------------------------------- 1 | .data 2 | foobar: 3 | .word 0 4 | .word 0 5 | .word 0 6 | .word 0 7 | .word 0 8 | .word 0 9 | .word 0 10 | .word 0 11 | 12 | .text 13 | .global main 14 | main: 15 | li $t0, 0xaabbccdd 16 | la $t1, foobar 17 | sb $t0, 0($t1) 18 | sb $t0, 1($t1) 19 | sb $t0, 3($t1) 20 | break 21 | 22 | -------------------------------------------------------------------------------- /debug-toolchain/sh-unaligned.s: -------------------------------------------------------------------------------- 1 | .data 2 | foobar: 3 | .word 0 4 | .word 0 5 | .word 0 6 | .word 0 7 | .word 0 8 | .word 0 9 | .word 0 10 | .word 0 11 | 12 | .text 13 | .global main 14 | main: 15 | li $t0, 0xaabbccdd 16 | la $t1, foobar 17 | sh $t0, 0($t1) 18 | sh $t0, 3($t1) 19 | break 20 | 21 | -------------------------------------------------------------------------------- /debug-toolchain/sh.s: -------------------------------------------------------------------------------- 1 | .data 2 | foobar: 3 | .word 0 4 | .word 0 5 | .word 0 6 | .word 0 7 | .word 0 8 | .word 0 9 | .word 0 10 | .word 0 11 | 12 | .text 13 | .global main 14 | main: 15 | li $t0, 0xaabbccdd 16 | la $t1, foobar 17 | sh $t0, 0($t1) 18 | sh $t0, 2($t1) 19 | sh $t0, 6($t1) 20 | break 21 | 22 | -------------------------------------------------------------------------------- /debug-toolchain/sll.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 40 5 | sll $t0, $t0, 20 6 | break 7 | -------------------------------------------------------------------------------- /debug-toolchain/sllv.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 40 5 | li $t1, 20 6 | sllv $t0, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/slt.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 17 5 | li $a1, 5 6 | li $a2, -17 7 | li $a3, -5 8 | slt $t0, $a0, $a1 9 | slt $t1, $a3, $a0 10 | slt $t2, $a2, $a3 11 | slt $t3, $a2, $a1 12 | break 13 | -------------------------------------------------------------------------------- /debug-toolchain/slti.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 100000 5 | li $a1, -100000 6 | slti $t0, $a0, -40 7 | slti $t1, $a0, 40 8 | slti $t2, $a1, -40 9 | slti $t3, $a1, 40 10 | break 11 | -------------------------------------------------------------------------------- /debug-toolchain/sltiu.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 100000 5 | li $a1, -100000 6 | sltiu $t0, $a0, -40 7 | sltiu $t1, $a0, 40 8 | sltiu $t2, $a1, -40 9 | sltiu $t3, $a1, 40 10 | break 11 | -------------------------------------------------------------------------------- /debug-toolchain/sltu.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 17 5 | li $a1, 5 6 | li $a2, -17 7 | li $a3, -5 8 | sltu $t0, $a0, $a1 9 | sltu $t1, $a3, $a0 10 | sltu $t2, $a2, $a3 11 | sltu $t3, $a2, $a1 12 | break 13 | -------------------------------------------------------------------------------- /debug-toolchain/sra.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, -15254 5 | sra $t0, $t0, 20 6 | break 7 | -------------------------------------------------------------------------------- /debug-toolchain/srav.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, -15254 5 | li $t1, 20 6 | srav $t0, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/srl.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, -15254 5 | srl $t0, $t0, 20 6 | break 7 | -------------------------------------------------------------------------------- /debug-toolchain/srlv.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, -15254 5 | li $t1, 20 6 | srlv $t0, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/start.s: -------------------------------------------------------------------------------- 1 | ### 2 | ## 3 | # Entry point and setup for our RSP 4 | ## 5 | 6 | .equ RAM_SIZE, 4096 7 | 8 | .text 9 | .align 2 10 | .section .text 11 | .global rsp_mips_start 12 | .extern main 13 | .ent rsp_mips_start 14 | .type rsp_mips_start, @function 15 | 16 | rsp_mips_start: 17 | nop 18 | redo: 19 | li $a0, 0 # argc = 0, it will never be used anyways on this stuff. :D 20 | li $a1, 0 # argv = 0 21 | li $sp, (0x00700000 + RAM_SIZE - 4) # Set up stack. 22 | 23 | jal main 24 | j redo 25 | 26 | .end rsp_mips_start 27 | .size rsp_mips_start, .-rsp_mips_start 28 | 29 | -------------------------------------------------------------------------------- /debug-toolchain/sub.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 40 5 | li $t1, -20 6 | sub $t2, $t0, $t1 7 | subu $t3, $t0, $t1 8 | 9 | li $t0, -5 10 | li $t1, -4 11 | sub $t2, $t0, $t1 12 | subu $t3, $t0, $t1 13 | 14 | break 15 | -------------------------------------------------------------------------------- /debug-toolchain/sw-unaligned.s: -------------------------------------------------------------------------------- 1 | .data 2 | foobar: 3 | .word 0 4 | .word 0 5 | .word 0 6 | .word 0 7 | .word 0 8 | .word 0 9 | .word 0 10 | .word 0 11 | 12 | .text 13 | .global main 14 | main: 15 | li $t0, 0xaabbccdd 16 | la $t1, foobar 17 | sw $t0, 0($t1) 18 | sw $t0, 5($t1) 19 | sw $t0, 10($t1) 20 | sw $t0, 15($t1) 21 | break 22 | 23 | -------------------------------------------------------------------------------- /debug-toolchain/sw.s: -------------------------------------------------------------------------------- 1 | .data 2 | foobar: 3 | .word 0 4 | .word 0 5 | .word 0 6 | .word 0 7 | .word 0 8 | .word 0 9 | .word 0 10 | .word 0 11 | 12 | .text 13 | .global main 14 | main: 15 | li $t0, 0xaabbccdd 16 | la $t1, foobar 17 | sw $t0, 0($t1) 18 | sw $t0, 4($t1) 19 | sw $t0, 12($t1) 20 | break 21 | 22 | -------------------------------------------------------------------------------- /debug-toolchain/unconditional-delay-slot-before-break.s: -------------------------------------------------------------------------------- 1 | .text 2 | .set noreorder 3 | .global main 4 | main: 5 | jal foo 6 | break 7 | 8 | nop 9 | nop 10 | nop 11 | nop 12 | 13 | foo: 14 | break 15 | -------------------------------------------------------------------------------- /debug-toolchain/xor.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $t0, 17 5 | li $t1, 5 6 | xor $t2, $t0, $t1 7 | break 8 | -------------------------------------------------------------------------------- /debug-toolchain/xori.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global main 3 | main: 4 | li $a0, 500 5 | xori $t0, $a0, 50000 6 | break 7 | -------------------------------------------------------------------------------- /debug_jit.cpp: -------------------------------------------------------------------------------- 1 | #include "debug_jit.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | namespace JIT 10 | { 11 | 12 | struct DebugBlock::Impl 13 | { 14 | Impl() = default; 15 | Impl(Impl &&) = delete; 16 | void operator=(Impl &&) = delete; 17 | ~Impl(); 18 | 19 | void *dylib = nullptr; 20 | Func block = nullptr; 21 | string name, soname; 22 | 23 | bool compile(uint64_t hash, const std::string &source); 24 | }; 25 | 26 | DebugBlock::DebugBlock(const unordered_map &) 27 | { 28 | } 29 | 30 | DebugBlock::~DebugBlock() 31 | { 32 | } 33 | 34 | DebugBlock::Impl::~Impl() 35 | { 36 | if (dylib) 37 | dlclose(dylib); 38 | 39 | remove(soname.c_str()); 40 | remove(name.c_str()); 41 | } 42 | 43 | bool DebugBlock::compile(uint64_t hash, const std::string &source) 44 | { 45 | impl = unique_ptr(new Impl); 46 | bool ret = impl->compile(hash, source); 47 | if (ret) 48 | block = impl->block; 49 | return ret; 50 | } 51 | 52 | bool DebugBlock::Impl::compile(uint64_t hash, const std::string &source) 53 | { 54 | name = "/tmp/"; 55 | name += to_string(hash); 56 | soname = name; 57 | name += ".c"; 58 | soname += ".so"; 59 | 60 | FILE *file = fopen(name.c_str(), "w"); 61 | if (!file) 62 | return false; 63 | 64 | fputs(source.c_str(), file); 65 | fclose(file); 66 | 67 | char command[256]; 68 | if (sizeof(size_t) == 8) 69 | { 70 | sprintf(command, "gcc -o %s %s -shared -fpic -O0 -g -std=c99 -Wl,--unresolved-symbols=ignore-all", 71 | soname.c_str(), 72 | name.c_str()); 73 | } 74 | else if (sizeof(size_t) == 4) 75 | { 76 | sprintf(command, "gcc -m32 -o %s %s -shared -fpic -O0 -g -std=c99 -Wl,--unresolved-symbols=ignore-all", 77 | soname.c_str(), 78 | name.c_str()); 79 | } 80 | int ret = system(command); 81 | if (ret != 0) 82 | return false; 83 | 84 | dylib = dlopen(soname.c_str(), RTLD_LOCAL | RTLD_LAZY); 85 | if (!dylib) 86 | return false; 87 | 88 | block = reinterpret_cast(dlsym(dylib, "block_entry")); 89 | if (!dylib) 90 | return false; 91 | return true; 92 | } 93 | 94 | } // namespace JIT 95 | -------------------------------------------------------------------------------- /debug_jit.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_JIT_HPP__ 2 | #define DEBUG_JIT_HPP__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace JIT 10 | { 11 | using Func = void (*)(void *, void *); 12 | class DebugBlock 13 | { 14 | public: 15 | DebugBlock(const std::unordered_map &symbol_table); 16 | ~DebugBlock(); 17 | 18 | bool compile(uint64_t hash, const std::string &source); 19 | Func get_func() const 20 | { 21 | return block; 22 | } 23 | 24 | private: 25 | struct Impl; 26 | std::unique_ptr impl; 27 | Func block = nullptr; 28 | }; 29 | } // namespace JIT 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /debug_rsp.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RSP_HPP__ 2 | #define RSP_HPP__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "debug_jit.hpp" 11 | #include "llvm_jit.hpp" 12 | #include "rsp_op.hpp" 13 | #include "state.hpp" 14 | 15 | namespace RSP 16 | { 17 | #ifdef DEBUG_JIT 18 | using Block = JIT::DebugBlock; 19 | #else 20 | using Block = JIT::Block; 21 | #endif 22 | using Func = JIT::Func; 23 | 24 | 25 | class alignas(64) CPU 26 | { 27 | public: 28 | CPU(); 29 | ~CPU(); 30 | 31 | CPU(CPU &&) = delete; 32 | void operator=(CPU &&) = delete; 33 | 34 | void set_dmem(uint32_t *dmem) 35 | { 36 | state.dmem = dmem; 37 | } 38 | 39 | void set_imem(uint32_t *imem) 40 | { 41 | state.imem = imem; 42 | } 43 | 44 | void set_rdram(uint32_t *rdram) 45 | { 46 | state.rdram = rdram; 47 | } 48 | 49 | void invalidate_imem(); 50 | 51 | CPUState &get_state() 52 | { 53 | return state; 54 | } 55 | 56 | ReturnMode run(); 57 | 58 | void enter(uint32_t pc); 59 | void call(uint32_t target, uint32_t ret); 60 | int ret(uint32_t pc); 61 | void exit(ReturnMode mode); 62 | 63 | void print_registers(); 64 | 65 | private: 66 | CPUState state; 67 | Func blocks[IMEM_WORDS] = {}; 68 | std::unordered_map symbol_table; 69 | #ifndef DEBUG_JIT 70 | JIT::LLVMEngine jit_engine; 71 | #endif 72 | std::unordered_map> cached_blocks[IMEM_WORDS]; 73 | 74 | void invalidate_code(); 75 | uint64_t hash_imem(unsigned pc, unsigned count) const; 76 | Func jit_region(uint64_t hash, unsigned pc, unsigned count); 77 | 78 | std::string full_code; 79 | std::string body; 80 | 81 | void init_symbol_table(); 82 | 83 | alignas(64) uint32_t cached_imem[IMEM_WORDS] = {}; 84 | 85 | // Platform specific. 86 | #ifdef __GNUC__ 87 | intptr_t env[64]; 88 | // We're reading this after setjmp returns so need to make sure the read happens when we expect it to. 89 | volatile ReturnMode return_mode; 90 | #else 91 | #error "Need __builtin_setjmp/longjmp support alternative for other compilers ..." 92 | #endif 93 | 94 | #define CALL_STACK_SIZE 32 95 | uint32_t call_stack[CALL_STACK_SIZE] = {}; 96 | unsigned call_stack_ptr = 0; 97 | 98 | unsigned analyze_static_end(unsigned pc, unsigned end); 99 | }; 100 | } // namespace RSP 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /format_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for file in arch/*/*/*.{cpp,h} *.{cpp,hpp,h} rsp/*.{cpp,h} 4 | do 5 | echo "Formatting file: $file ..." 6 | clang-format -style=file -i $file 7 | done 8 | -------------------------------------------------------------------------------- /jit_allocator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace RSP 7 | { 8 | namespace JIT 9 | { 10 | class Allocator 11 | { 12 | public: 13 | Allocator() = default; 14 | ~Allocator(); 15 | void operator=(const Allocator &) = delete; 16 | Allocator(const Allocator &) = delete; 17 | 18 | void *allocate_code(size_t size); 19 | static bool commit_code(void *code, size_t size); 20 | 21 | private: 22 | struct Block 23 | { 24 | uint8_t *code = nullptr; 25 | size_t size = 0; 26 | size_t offset = 0; 27 | }; 28 | std::vector blocks; 29 | 30 | static Block reserve_block(size_t size); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lightning/.gitattributes: -------------------------------------------------------------------------------- 1 | ChangeLog merge=merge-changelog 2 | -------------------------------------------------------------------------------- /lightning/.gitignore: -------------------------------------------------------------------------------- 1 | /build-aux 2 | +* 3 | 4 | *.o 5 | *.lo 6 | *.la 7 | 8 | .libs/ 9 | .deps/ 10 | */.libs/ 11 | */.deps/ 12 | 13 | autom4te.cache 14 | aclocal.m4 15 | depcomp 16 | INSTALL 17 | Makefile 18 | Makefile.in 19 | config.guess 20 | config.h 21 | config.h.in 22 | config.log 23 | config.status 24 | config.sub 25 | configure 26 | install-sh 27 | libtool 28 | lightning-*.tar.* 29 | ltmain.sh 30 | missing 31 | size 32 | stamp-h1 33 | test-driver 34 | 35 | m4/libtool.m4 36 | m4/lt~obsolete.m4 37 | m4/ltoptions.m4 38 | m4/ltsugar.m4 39 | m4/ltversion.m4 40 | 41 | lightning.pc 42 | include/lightning.h 43 | 44 | build-aux/ 45 | -------------------------------------------------------------------------------- /lightning/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gnulib"] 2 | path = gnulib 3 | url = git://git.sv.gnu.org/gnulib.git 4 | -------------------------------------------------------------------------------- /lightning/.gitrepo: -------------------------------------------------------------------------------- 1 | ; DO NOT EDIT (unless you know what you are doing) 2 | ; 3 | ; This subdirectory is a git "subrepo", and this file is maintained by the 4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme 5 | ; 6 | [subrepo] 7 | remote = https://git.savannah.gnu.org/git/lightning.git 8 | branch = master 9 | commit = 75e5274ba59feab99a2afcf329d890911ed01eaf 10 | parent = b7d23a9d07791c7006d57c58ab1e442103741cd6 11 | method = merge 12 | cmdver = 0.4.5 13 | -------------------------------------------------------------------------------- /lightning/AUTHORS: -------------------------------------------------------------------------------- 1 | Paulo Cesar Pereira de Andrade 2 | 3 | Paolo Bonzini 4 | 5 | PPC assembler by Ian Piumarta 6 | 7 | i386 assembler by Ian Piumarta 8 | and Gwenole Beauchesne 9 | 10 | x86-64 backend by Matthew Flatt 11 | 12 | Major PPC contributions by Laurent Michel 13 | 14 | Major SPARC contributions by Ludovic Courtes 15 | -------------------------------------------------------------------------------- /lightning/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2000, 2001, 2002, 2012-2023 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU lightning. 5 | # 6 | # GNU lightning is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as published 8 | # by the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU lightning is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | # License for more details. 15 | # 16 | 17 | ACLOCAL_AMFLAGS = -I m4 18 | 19 | SUBDIRS = \ 20 | gnulib-lib \ 21 | check \ 22 | doc \ 23 | include \ 24 | lib 25 | 26 | EXTRA_DIST = m4/gnulib-cache.m4 27 | 28 | pkgconfiglibdir = $(libdir)/pkgconfig 29 | pkgconfiglib_DATA = lightning.pc 30 | 31 | if get_jit_size 32 | JIT_SIZE_PATH = "$(top_builddir)/jit_$(cpu)-sz.c" 33 | AM_CPPFLAGS=-DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)' 34 | AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ 35 | -D_GNU_SOURCE $(LIGHTNING_CFLAGS) 36 | 37 | noinst_PROGRAMS = size 38 | size_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 39 | size_SOURCES = size.c 40 | 41 | get_jit_size:: $(JIT_SIZE_PATH) 42 | 43 | $(JIT_SIZE_PATH): 44 | make clean 45 | make check 46 | $(top_builddir)/size 47 | 48 | CLEANFILES = $(JIT_SIZE_PATH) 49 | endif 50 | -------------------------------------------------------------------------------- /lightning/README: -------------------------------------------------------------------------------- 1 | GNU lightning is a library to aid in making portable programs 2 | that compile assembly code at run time. For more information, 3 | look at the info documentation. 4 | 5 | For help building lightning, see README-hacking. 6 | -------------------------------------------------------------------------------- /lightning/THANKS: -------------------------------------------------------------------------------- 1 | Thanks to all the following people for their help in 2 | improving GNU lightning: 3 | 4 | Paolo Bonzini 5 | Eli Barzilay 6 | Ludovic Courtes 7 | Matthew Flatt 8 | Laurent Michel 9 | Paulo Cesar Pereira de Andrade 10 | Mike Spivey 11 | Basile Starynkevitch 12 | Sam Steingold 13 | Jens Troeger 14 | Tom Tromey 15 | Trent Nelson 16 | Vitaly Magerya 17 | Brandon Invergo 18 | Holger Hans Peter Freyther 19 | Jon Arintok 20 | Bruno Haible 21 | Marc Nieper-Wißkirchen 22 | Paul Cercueil 23 | -------------------------------------------------------------------------------- /lightning/TODO: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lightning/bootstrap.conf: -------------------------------------------------------------------------------- 1 | # Bootstrap configuration. 2 | 3 | # Copyright (C) 2006-2020 Free Software Foundation, Inc. 4 | 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3 of the License, or 8 | # (at your option) any later version. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | 19 | # gnulib modules used by this package. 20 | gnulib_modules=" 21 | " 22 | 23 | # gnulib library name. 24 | gnulib_name=libgnu 25 | 26 | # directories. 27 | source_base=gnulib-lib 28 | doc_base=gnulib-doc 29 | 30 | # Additional xgettext options to use. Use "\\\newline" to break lines. 31 | XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ 32 | --from-code=UTF-8\\\ 33 | --flag=asprintf:2:c-format --flag=vasprintf:2:c-format\\\ 34 | --flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\ 35 | --flag=wrapf:1:c-format\\\ 36 | ' 37 | 38 | # If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]" 39 | # appears in configure.ac, exclude some unnecessary files. 40 | # Without grep's -E option (not portable enough, pre-configure), 41 | # the following test is ugly. Also, this depends on the existence 42 | # of configure.ac, not the obsolescent-named configure.in. But if 43 | # you're using this infrastructure, you should care about such things. 44 | 45 | gettext_external=0 46 | grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null && 47 | gettext_external=1 48 | grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null && 49 | gettext_external=1 50 | 51 | if test $gettext_external = 1; then 52 | # Gettext supplies these files, but we don't need them since 53 | # we don't have an intl subdirectory. 54 | excluded_files=' 55 | m4/glibc2.m4 56 | m4/intdiv0.m4 57 | m4/lcmessage.m4 58 | m4/lock.m4 59 | m4/printf-posix.m4 60 | m4/size_max.m4 61 | m4/uintmax_t.m4 62 | m4/ulonglong.m4 63 | m4/visibility.m4 64 | m4/xsize.m4 65 | ' 66 | fi 67 | 68 | # Build prerequisites 69 | buildreq="\ 70 | autoconf 2.59 71 | automake 1.9.6 72 | git 1.5.5 73 | tar - 74 | " 75 | 76 | bootstrap_sync=true 77 | -------------------------------------------------------------------------------- /lightning/check/.gitignore: -------------------------------------------------------------------------------- 1 | *.nodata 2 | nodata 3 | *.log 4 | *.trs 5 | 6 | 3to2 7 | bswap 8 | add 9 | align 10 | allocai 11 | allocar 12 | alu_add 13 | alu_and 14 | alu_com 15 | alu_div 16 | alu_lsh 17 | alu_mul 18 | alu_neg 19 | alu_or 20 | alu_rem 21 | alu_rsb 22 | alu_rsh 23 | alu_sub 24 | alu_xor 25 | alux_add 26 | alux_sub 27 | bp 28 | branch 29 | call 30 | carg 31 | carry 32 | catomic 33 | ccall 34 | clobber 35 | ctramp 36 | cva_list 37 | cvt 38 | divi 39 | fib 40 | float 41 | fop_abs 42 | fop_sqrt 43 | hton 44 | jmpr 45 | ldsti 46 | ldstr 47 | ldstr-c 48 | ldstxi 49 | ldstxi-c 50 | ldstxr 51 | ldstxr-c 52 | lightning 53 | live 54 | movzr 55 | put 56 | qalu_div 57 | qalu_mul 58 | range 59 | ranger 60 | ret 61 | rpn 62 | self 63 | setcode 64 | stack 65 | tramp 66 | va_list 67 | varargs 68 | -------------------------------------------------------------------------------- /lightning/check/3to2.ok: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 1 4 | 1 5 | 0 6 | 1 7 | 1 8 | 1 9 | 0 10 | 1 11 | 1 12 | 0 13 | 1 14 | 1 15 | 1 16 | 0 17 | 1 18 | 1 19 | 1 20 | 0 21 | 1 22 | 1 23 | -------------------------------------------------------------------------------- /lightning/check/3to2.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | dfmt: 3 | .c "%1.0f\n" 4 | ifmt: 5 | .c "%d\n" 6 | 7 | .code 8 | jmpi main 9 | 10 | #define def_test_double(a, b, c) \ 11 | name test_double_##a##_##b##_##c \ 12 | test_double_##a##_##b##_##c: \ 13 | prolog \ 14 | arg_d $d0 \ 15 | arg_d $d1 \ 16 | getarg_d %b $d0 \ 17 | getarg_d %c $d1 \ 18 | subr_d %a %b %c \ 19 | retr_d %a \ 20 | epilog 21 | #define test_double(a, b, c, x, y) \ 22 | prepare \ 23 | pushargi_d x \ 24 | pushargi_d y \ 25 | finishi test_double_##a##_##b##_##c \ 26 | retval_d %f0 \ 27 | prepare \ 28 | pushargi dfmt \ 29 | ellipsis \ 30 | pushargr_d %f0 \ 31 | finishi @printf 32 | 33 | #define def_test_int(a, b, c) \ 34 | name test_int_##a##_##b##_##c \ 35 | test_int_##a##_##b##_##c: \ 36 | prolog \ 37 | arg $i0 \ 38 | arg $i1 \ 39 | getarg %b $i0 \ 40 | getarg %c $i1 \ 41 | subr %a %b %c \ 42 | retr %a \ 43 | epilog 44 | #define test_int(a, b, c, x, y) \ 45 | prepare \ 46 | pushargi x \ 47 | pushargi y \ 48 | finishi test_int_##a##_##b##_##c \ 49 | retval %r0 \ 50 | prepare \ 51 | pushargi ifmt \ 52 | ellipsis \ 53 | pushargr %r0 \ 54 | finishi @printf 55 | 56 | def_test_double(f0, f0, f0) 57 | def_test_double(f0, f0, f1) 58 | def_test_double(f0, f1, f0) 59 | def_test_double(f0, f1, f2) 60 | 61 | def_test_double(f3, f3, f3) 62 | def_test_double(f3, f3, f1) 63 | def_test_double(f3, f1, f3) 64 | def_test_double(f3, f1, f2) 65 | 66 | def_test_double(f3, f0, f0) 67 | def_test_double(f3, f0, f3) 68 | def_test_double(f3, f3, f0) 69 | 70 | def_test_int(r0, r0, r0) 71 | def_test_int(r0, r0, r1) 72 | def_test_int(r0, r1, r0) 73 | def_test_int(r0, r1, r2) 74 | 75 | def_test_int(v0, v0, v0) 76 | def_test_int(v0, v0, r1) 77 | def_test_int(v0, r1, v0) 78 | def_test_int(v0, r1, r2) 79 | 80 | def_test_int(v0, r0, r0) 81 | def_test_int(v0, r0, v0) 82 | def_test_int(v0, v0, r0) 83 | 84 | 85 | name main 86 | main: 87 | prolog 88 | 89 | test_double(f0, f0, f0, 3.0, 2.0) 90 | test_double(f0, f0, f1, 3.0, 2.0) 91 | test_double(f0, f1, f0, 3.0, 2.0) 92 | test_double(f0, f1, f2, 3.0, 2.0) 93 | 94 | test_double(f3, f3, f3, 3.0, 2.0) 95 | test_double(f3, f3, f1, 3.0, 2.0) 96 | test_double(f3, f1, f3, 3.0, 2.0) 97 | test_double(f3, f1, f2, 3.0, 2.0) 98 | 99 | test_double(f3, f0, f0, 3.0, 2.0) 100 | test_double(f3, f0, f3, 3.0, 2.0) 101 | test_double(f3, f3, f0, 3.0, 2.0) 102 | 103 | test_int(r0, r0, r0, 3, 2) 104 | test_int(r0, r0, r1, 3, 2) 105 | test_int(r0, r1, r0, 3, 2) 106 | test_int(r0, r1, r2, 3, 2) 107 | 108 | test_int(v0, v0, v0, 3, 2) 109 | test_int(v0, v0, r1, 3, 2) 110 | test_int(v0, r1, v0, 3, 2) 111 | test_int(v0, r1, r2, 3, 2) 112 | 113 | test_int(v0, r0, r0, 3, 2) 114 | test_int(v0, r0, v0, 3, 2) 115 | test_int(v0, v0, r0, 3, 2) 116 | 117 | ret 118 | epilog 119 | -------------------------------------------------------------------------------- /lightning/check/add.ok: -------------------------------------------------------------------------------- 1 | 5 + 4 = 9 2 | -------------------------------------------------------------------------------- /lightning/check/add.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | fmt: 3 | .c "%d + %d = %d\n" 4 | 5 | .code 6 | jmpi main 7 | 8 | name test 9 | test: 10 | prolog 11 | arg $i0 12 | arg $i1 13 | getarg %r0 $i0 14 | getarg %r1 $i1 15 | addr %r0 %r0 %r1 16 | retr %r0 17 | epilog 18 | 19 | name main 20 | main: 21 | prolog 22 | prepare 23 | pushargi 5 24 | pushargi 4 25 | finishi test 26 | retval %r0 27 | prepare 28 | pushargi fmt 29 | ellipsis 30 | pushargi 5 31 | pushargi 4 32 | pushargr %r0 33 | finishi @printf 34 | ret 35 | epilog 36 | -------------------------------------------------------------------------------- /lightning/check/align.ok: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /lightning/check/align.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | fmt: 3 | .c "%d\n" 4 | .code 5 | prolog 6 | movi %r0 1 7 | jmpi L1 /* should not generate this */ 8 | align $(__WORDSIZE / 8) /* possible nops */ 9 | L1: 10 | bgei L4 %r0 10 11 | addi %r0 %r0 1 12 | jmpi L2 13 | movr %r1 %r0 /* to force jump generation */ 14 | align $(__WORDSIZE / 8) /* possible nops */ 15 | L2: 16 | bgti L4 %r0 10 /* never executed */ 17 | align $(__WORDSIZE / 8) /* possible nops */ 18 | L3: 19 | jmpi L1 20 | align 32 /* Force nops */ 21 | L4: 22 | prepare 23 | pushargi fmt 24 | ellipsis 25 | pushargr %r0 26 | finishi @printf 27 | ret 28 | epilog 29 | -------------------------------------------------------------------------------- /lightning/check/allocai.ok: -------------------------------------------------------------------------------- 1 | received 7777 2 | succeeded 3 | -------------------------------------------------------------------------------- /lightning/check/allocai.tst: -------------------------------------------------------------------------------- 1 | .data 128 2 | idfmt: 3 | .c "received %d\n" 4 | failure_message: 5 | .c "numbers don't add up to zero\n" 6 | report_message: 7 | .c "failed: got %i instead of %i\n" 8 | succeeded_message: 9 | .c "succeeded\n" 10 | 11 | .code 12 | jmpi main 13 | 14 | /* 15 | static int 16 | identity (int arg) 17 | { 18 | printf ("received %i\n", arg); 19 | return arg; 20 | } 21 | */ 22 | name identify 23 | identify: 24 | prolog 25 | arg $i 26 | getarg %v0 $i 27 | prepare 28 | pushargi idfmt 29 | ellipsis 30 | pushargr %v0 31 | finishi @printf 32 | retr %v0 33 | epilog 34 | 35 | name identity_func 36 | identity_func: 37 | prolog 38 | arg $i 39 | getarg %r1 $i 40 | 41 | /* Store the argument on the stack. */ 42 | allocai $(__WORDSIZE >> 3) $off 43 | stxi $off %fp %r1 44 | 45 | /* Store the negative of the argument on the stack. */ 46 | allocai $(__WORDSIZE >> 3) $neg 47 | negr %r2 %r1 48 | stxi $neg %fp %r2 49 | 50 | /* Invoke FUNC. */ 51 | prepare 52 | pushargr %r1 53 | finishi identify 54 | 55 | /* Ignore the result. */ 56 | 57 | /* Restore the negative and the argument from the stack. */ 58 | ldxi %r2 %fp $neg 59 | ldxi %v1 %fp $off 60 | 61 | /* Make sure they still add to zero. */ 62 | addr %r0 %v1 %r2 63 | bnei branch %r0 0 64 | 65 | /* Return it. */ 66 | retr %v1 67 | 68 | /* Display a failure message. */ 69 | branch: 70 | prepare 71 | pushargi failure_message 72 | ellipsis 73 | finishi @printf 74 | 75 | /* Leave. */ 76 | retr %v1 77 | epilog 78 | 79 | name main 80 | main: 81 | prolog 82 | prepare 83 | pushargi 7777 84 | finishi identity_func 85 | retval %r0 86 | beqi succeeded %r0 7777 87 | prepare 88 | pushargi report_message 89 | ellipsis 90 | pushargr %r0 91 | pushargi 7777 92 | finishi @printf 93 | reti 1 94 | succeeded: 95 | prepare 96 | pushargi succeeded_message 97 | ellipsis 98 | finishi @printf 99 | reti 0 100 | epilog 101 | -------------------------------------------------------------------------------- /lightning/check/allocar.ok: -------------------------------------------------------------------------------- 1 | 1 2 3 2 | 3 4 5 3 | 5 6 7 4 | 7 8 9 5 | -------------------------------------------------------------------------------- /lightning/check/alu_add.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_add.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define ADD(N, I0, I1, V) ALU(N, , add, I0, I1, V) 7 | 8 | ADD(0, 0x7fffffff, 1, 0x80000000) 9 | ADD(1, 1, 0x7fffffff, 0x80000000) 10 | ADD(2, 0x80000000, 1, 0x80000001) 11 | ADD(3, 1, 0x80000000, 0x80000001) 12 | ADD(4, 0x7fffffff, 0x80000000, 0xffffffff) 13 | ADD(5, 0x80000000, 0x7fffffff, 0xffffffff) 14 | ADD(6, 0x7fffffff, 0, 0x7fffffff) 15 | ADD(7, 0, 0x7fffffff, 0x7fffffff) 16 | #if __WORDSIZE == 32 17 | ADD(8, 0x7fffffff, 0xffffffff, 0x7ffffffe) 18 | ADD(9, 0xffffffff, 0x7fffffff, 0x7ffffffe) 19 | ADD(10, 0xffffffff, 0xffffffff, 0xfffffffe) 20 | #else 21 | ADD(8, 0x7fffffff, 0xffffffff, 0x17ffffffe) 22 | ADD(9, 0xffffffff, 0x7fffffff, 0x17ffffffe) 23 | ADD(10, 0xffffffff, 0xffffffff, 0x1fffffffe) 24 | ADD(11, 0x7fffffffffffffff, 1, 0x8000000000000000) 25 | ADD(12, 1, 0x7fffffffffffffff, 0x8000000000000000) 26 | ADD(13, 0x8000000000000000, 1, 0x8000000000000001) 27 | ADD(14, 1, 0x8000000000000000, 0x8000000000000001) 28 | ADD(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) 29 | ADD(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 30 | ADD(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffffe) 31 | ADD(18, 0x7fffffffffffffff, 0x7fffffffffffffff, 0xfffffffffffffffe) 32 | ADD(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffffe) 33 | #endif 34 | 35 | #undef ADD 36 | #define ADD(N, T, I0, I1, V) FOP(N, T, add, I0, I1, V) 37 | ADD(0, _f, -0.5, 0.5, 0.0) 38 | ADD(1, _f, 0.25, 0.75, 1.0) 39 | ADD(0, _d, -0.5, 0.5, 0.0) 40 | ADD(1, _d, 0.25, 0.75, 1.0) 41 | 42 | prepare 43 | pushargi ok 44 | ellipsis 45 | finishi @printf 46 | ret 47 | epilog 48 | -------------------------------------------------------------------------------- /lightning/check/alu_and.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_and.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define AND(N, I0, I1, V) ALU(N, , and, I0, I1, V) 7 | 8 | AND(0, 0x7fffffff, 1, 1) 9 | AND(1, 1, 0x7fffffff, 1) 10 | AND(2, 0x80000000, 1, 0) 11 | AND(3, 1, 0x80000000, 0) 12 | AND(4, 0x7fffffff, 0x80000000, 0) 13 | AND(5, 0x80000000, 0x7fffffff, 0) 14 | AND(6, 0x7fffffff, 0xffffffff, 0x7fffffff) 15 | AND(7, 0xffffffff, 0x7fffffff, 0x7fffffff) 16 | AND(8, 0xffffffff, 0xffffffff, 0xffffffff) 17 | AND(9, 0x7fffffff, 0, 0) 18 | AND(10, 0, 0x7fffffff, 0) 19 | #if __WORDSIZE == 64 20 | AND(11, 0x7fffffffffffffff, 1, 1) 21 | AND(12, 1, 0x7fffffffffffffff, 1) 22 | AND(13, 0x8000000000000000, 1, 0) 23 | AND(14, 1, 0x8000000000000000, 0) 24 | AND(15, 0x7fffffffffffffff, 0x8000000000000000, 0) 25 | AND(16, 0x8000000000000000, 0x7fffffffffffffff, 0) 26 | AND(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff) 27 | AND(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0x7fffffffffffffff) 28 | AND(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) 29 | #endif 30 | 31 | prepare 32 | pushargi ok 33 | ellipsis 34 | finishi @printf 35 | ret 36 | epilog 37 | -------------------------------------------------------------------------------- /lightning/check/alu_com.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_com.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define COM(N, I0, V) UN(N, com, I0, V) 7 | 8 | #if __WORDSIZE == 32 9 | COM(0, 0, 0xffffffff) 10 | COM(1, 1, 0xfffffffe) 11 | COM(2, 0xffffffff, 0) 12 | COM(3, 0x80000000, 0x7fffffff) 13 | COM(4, 0x7fffffff, 0x80000000) 14 | COM(5, 0x80000001, 0x7ffffffe) 15 | #else 16 | COM(0, 0, 0xffffffffffffffff) 17 | COM(1, 1, 0xfffffffffffffffe) 18 | COM(2, 0xffffffff, 0xffffffff00000000) 19 | COM(3, 0x80000000, 0xffffffff7fffffff) 20 | COM(4, 0x7fffffff, 0xffffffff80000000) 21 | COM(5, 0x80000001, 0xffffffff7ffffffe) 22 | COM(6, 0xffffffffffffffff, 0) 23 | COM(7, 0x8000000000000000, 0x7fffffffffffffff) 24 | COM(8, 0x7fffffffffffffff, 0x8000000000000000) 25 | COM(9, 0x8000000000000001, 0x7ffffffffffffffe) 26 | #endif 27 | 28 | prepare 29 | pushargi ok 30 | ellipsis 31 | finishi @printf 32 | ret 33 | epilog 34 | -------------------------------------------------------------------------------- /lightning/check/alu_div.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_div.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define DIV(N, I0, I1, V) ALU(N, , div, I0, I1, V) 7 | #define UDIV(N, I0, I1, V) ALU(N, _u, div, I0, I1, V) 8 | 9 | DIV(0, 0x7fffffff, 1, 0x7fffffff) 10 | DIV(1, 1, 0x7fffffff, 0) 11 | DIV(2, 0x80000000, 1, 0x80000000) 12 | DIV(3, 1, 0x80000000, 0) 13 | DIV(4, 0x7fffffff, 2, 0x3fffffff) 14 | DIV(5, 2, 0x7fffffff, 0) 15 | DIV(6, 2, 0x80000000, 0) 16 | DIV(7, 0x7fffffff, 0x80000000, 0) 17 | DIV(8, 0, 0x7fffffff, 0) 18 | DIV(9, 0xffffffff, 0xffffffff, 1) 19 | UDIV(0, 0x7fffffff, 1, 0x7fffffff) 20 | UDIV(1, 1, 0x7fffffff, 0) 21 | UDIV(2, 0x80000000, 1, 0x80000000) 22 | UDIV(3, 1, 0x80000000, 0) 23 | UDIV(4, 0x7fffffff, 2, 0x3fffffff) 24 | UDIV(5, 2, 0x7fffffff, 0) 25 | UDIV(6, 0x80000000, 2, 0x40000000) 26 | UDIV(7, 2, 0x80000000, 0) 27 | UDIV(8, 0x7fffffff, 0x80000000, 0) 28 | UDIV(9, 0x80000000, 0x7fffffff, 1) 29 | UDIV(10,0, 0x7fffffff, 0) 30 | UDIV(11,0x7fffffff, 0xffffffff, 0) 31 | UDIV(12,0xffffffff, 0x7fffffff, 2) 32 | UDIV(13,0xffffffff, 0xffffffff, 1) 33 | #if __WORDSIZE == 32 34 | DIV(10, 0x80000000, 2, 0xc0000000) 35 | DIV(11, 0x80000000, 0x7fffffff, 0xffffffff) 36 | DIV(12, 0x7fffffff, 0xffffffff, 0x80000001) 37 | DIV(13, 0xffffffff, 0x7fffffff, 0) 38 | #else 39 | DIV(10, 0x80000000, 2, 0x40000000) 40 | DIV(11, 0x80000000, 0x7fffffff, 1) 41 | DIV(12, 0x7fffffff, 0xffffffff, 0) 42 | DIV(13, 0xffffffff, 0x7fffffff, 2) 43 | DIV(14, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) 44 | DIV(15, 1, 0x7fffffffffffffff, 0) 45 | DIV(16, 0x8000000000000000, 1, 0x8000000000000000) 46 | DIV(17, 1, 0x8000000000000000, 0) 47 | DIV(18, 0x7fffffffffffffff, 2, 0x3fffffffffffffff) 48 | DIV(19, 2, 0x7fffffffffffffff, 0) 49 | DIV(20, 0x8000000000000000, 2, 0xc000000000000000) 50 | DIV(21, 2, 0x8000000000000000, 0) 51 | DIV(22, 0x7fffffffffffffff, 0x8000000000000000, 0) 52 | DIV(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 53 | DIV(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001) 54 | DIV(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0) 55 | DIV(26, 0xffffffffffffffff, 0xffffffffffffffff, 1) 56 | UDIV(14,0x7fffffffffffffff, 1, 0x7fffffffffffffff) 57 | UDIV(15,1, 0x7fffffffffffffff, 0) 58 | UDIV(16,0x8000000000000000, 1, 0x8000000000000000) 59 | UDIV(17,1, 0x8000000000000000, 0) 60 | UDIV(18,0x7fffffffffffffff, 2, 0x3fffffffffffffff) 61 | UDIV(19,2, 0x7fffffffffffffff, 0) 62 | UDIV(20,0x8000000000000000, 2, 0x4000000000000000) 63 | UDIV(21,2, 0x8000000000000000, 0) 64 | UDIV(22,0x7fffffffffffffff, 0x8000000000000000, 0) 65 | UDIV(23,0x8000000000000000, 0x7fffffffffffffff, 1) 66 | UDIV(24,0x7fffffffffffffff, 0xffffffffffffffff, 0) 67 | UDIV(25,0xffffffffffffffff, 0x7fffffffffffffff, 2) 68 | UDIV(26,0xffffffffffffffff, 0xffffffffffffffff, 1) 69 | #endif 70 | 71 | #undef DIV 72 | #define DIV(N, T, I0, I1, V) FOP(N, T, div, I0, I1, V) 73 | DIV(0, _f, -0.5, 0.5, -1.0) 74 | DIV(1, _f, 1.25, 0.5, 2.5) 75 | DIV(0, _d, -0.5, 0.5, -1.0) 76 | DIV(1, _d, 1.25, 0.5, 2.5) 77 | 78 | prepare 79 | pushargi ok 80 | ellipsis 81 | finishi @printf 82 | ret 83 | epilog 84 | -------------------------------------------------------------------------------- /lightning/check/alu_lsh.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_lsh.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define LSH(N, I0, I1, V) ALU(N, , lsh, I0, I1, V) 7 | 8 | LSH(0, 0x7f, 1, 0xfe) 9 | LSH(1, 0x7fff, 2, 0x1fffc) 10 | LSH(2, 0x81, 16, 0x810000) 11 | LSH(3, 0xff, 15, 0x7f8000) 12 | LSH(4, 0x7fffffff, 0, 0x7fffffff) 13 | #if __WORDSIZE == 32 14 | LSH(5, 0xffffffff, 8, 0xffffff00) 15 | LSH(6, 0x7fffffff, 3, 0xfffffff8) 16 | LSH(7, -0x7f, 31, 0x80000000) 17 | LSH(8, -0x7fff, 30, 0x40000000) 18 | LSH(9, -0x7fffffff, 29, 0x20000000) 19 | LSH(10, 0x80000001, 28, 0x10000000) 20 | LSH(11, 0x8001, 17, 0x20000) 21 | LSH(12, 0x80000001, 18, 0x40000) 22 | LSH(13, -0xffff, 24, 0x1000000) 23 | #else 24 | LSH(5, 0xffffffff, 8, 0xffffffff00) 25 | LSH(6, 0x7fffffff, 3, 0x3fffffff8) 26 | LSH(7, -0x7f, 31, 0xffffffc080000000) 27 | LSH(8, -0x7fff, 30, 0xffffe00040000000) 28 | LSH(9, -0x7fffffff, 29, 0xf000000020000000) 29 | LSH(10, 0x80000001, 28, 0x800000010000000) 30 | LSH(11, 0x8001, 17, 0x100020000) 31 | LSH(12, 0x80000001, 18, 0x2000000040000) 32 | LSH(13, -0xffff, 24, 0xffffff0001000000) 33 | LSH(14, 0x7f, 33, 0xfe00000000) 34 | LSH(15, 0x7ffff, 34, 0x1ffffc00000000) 35 | LSH(16, 0x7fffffff, 35, 0xfffffff800000000) 36 | LSH(17, -0x7f, 63, 0x8000000000000000) 37 | LSH(18, -0x7fff, 62, 0x4000000000000000) 38 | LSH(19, -0x7fffffff, 61, 0x2000000000000000) 39 | LSH(20, 0x80000001, 60, 0x1000000000000000) 40 | LSH(21, 0x81, 48, 0x81000000000000) 41 | LSH(22, 0x8001, 49, 0x2000000000000) 42 | LSH(23, 0x80000001, 40, 0x10000000000) 43 | LSH(24, 0xff, 47, 0x7f800000000000) 44 | LSH(25, 0xffff0001, 56, 0x100000000000000) 45 | LSH(26, 0xffffffff, 40, 0xffffff0000000000) 46 | LSH(27, 0x7fffffffff, 33, 0xfffffffe00000000) 47 | LSH(28, -0x7fffffffff, 63, 0x8000000000000000) 48 | LSH(29, 0x8000000001, 48, 0x1000000000000) 49 | LSH(30, 0xffffffffff, 47, 0xffff800000000000) 50 | #endif 51 | 52 | prepare 53 | pushargi ok 54 | ellipsis 55 | finishi @printf 56 | ret 57 | epilog 58 | -------------------------------------------------------------------------------- /lightning/check/alu_mul.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_mul.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define MUL(N, I0, I1, V) ALU(N, , mul, I0, I1, V) 7 | 8 | MUL(0, 0x7fffffff, 1, 0x7fffffff) 9 | MUL(1, 1, 0x7fffffff, 0x7fffffff) 10 | MUL(2, 0x80000000, 1, 0x80000000) 11 | MUL(3, 1, 0x80000000, 0x80000000) 12 | MUL(4, 0x7fffffff, 2, 0xfffffffe) 13 | MUL(5, 2, 0x7fffffff, 0xfffffffe) 14 | MUL(6, 0x7fffffff, 0, 0) 15 | MUL(7, 0, 0x7fffffff, 0) 16 | #if __WORDSIZE == 32 17 | MUL(8, 0x80000000, 2, 0) 18 | MUL(9, 2, 0x80000000, 0) 19 | MUL(10, 0x7fffffff, 0x80000000, 0x80000000) 20 | MUL(11, 0x80000000, 0x7fffffff, 0x80000000) 21 | MUL(12, 0x7fffffff, 0xffffffff, 0x80000001) 22 | MUL(13, 0xffffffff, 0x7fffffff, 0x80000001) 23 | MUL(14, 0xffffffff, 0xffffffff, 1) 24 | #else 25 | MUL(8, 0x80000000, 2, 0x100000000) 26 | MUL(9, 2, 0x80000000, 0x100000000) 27 | MUL(10, 0x7fffffff, 0x80000000, 0x3fffffff80000000) 28 | MUL(11, 0x80000000, 0x7fffffff, 0x3fffffff80000000) 29 | MUL(12, 0x7fffffff, 0xffffffff, 0x7ffffffe80000001) 30 | MUL(13, 0xffffffff, 0x7fffffff, 0x7ffffffe80000001) 31 | MUL(14, 0xffffffff, 0xffffffff, 0xfffffffe00000001) 32 | MUL(15, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) 33 | MUL(16, 1, 0x7fffffffffffffff, 0x7fffffffffffffff) 34 | MUL(17, 0x8000000000000000, 1, 0x8000000000000000) 35 | MUL(18, 1, 0x8000000000000000, 0x8000000000000000) 36 | MUL(19, 0x7fffffffffffffff, 2, 0xfffffffffffffffe) 37 | MUL(20, 2, 0x7fffffffffffffff, 0xfffffffffffffffe) 38 | MUL(21, 0x8000000000000000, 2, 0) 39 | MUL(22, 2, 0x8000000000000000, 0) 40 | MUL(23, 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000000) 41 | MUL(24, 0x8000000000000000, 0x7fffffffffffffff, 0x8000000000000000) 42 | MUL(25, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001) 43 | MUL(26, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000001) 44 | MUL(27, 0xffffffffffffffff, 0xffffffffffffffff, 1) 45 | #endif 46 | 47 | #undef MUL 48 | #define MUL(N, T, I0, I1, V) FOP(N, T, mul, I0, I1, V) 49 | MUL(0, _f, -0.5, 0.5, -0.25) 50 | MUL(1, _f, 0.25, 0.75, 0.1875) 51 | MUL(0, _d, -0.5, 0.5, -0.25) 52 | MUL(1, _d, 0.25, 0.75, 0.1875) 53 | 54 | prepare 55 | pushargi ok 56 | ellipsis 57 | finishi @printf 58 | ret 59 | epilog 60 | -------------------------------------------------------------------------------- /lightning/check/alu_neg.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_neg.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define NEG(N, I, V) UN(N, neg, I, V) 7 | 8 | NEG(0, 0, 0) 9 | #if __WORDSIZE == 32 10 | NEG(1, 1, 0xffffffff) 11 | NEG(2, 0xffffffff, 1) 12 | NEG(3, 0x80000000, 0x80000000) 13 | NEG(4, 0x7fffffff, 0x80000001) 14 | NEG(5, 0x80000001, 0x7fffffff) 15 | #else 16 | NEG(1, 1, 0xffffffffffffffff) 17 | NEG(2, 0xffffffff, 0xffffffff00000001) 18 | NEG(3, 0x80000000, 0xffffffff80000000) 19 | NEG(4, 0x7fffffff, 0xffffffff80000001) 20 | NEG(5, 0x80000001, 0xffffffff7fffffff) 21 | NEG(6, 0xffffffffffffffff, 1) 22 | NEG(7, 0x8000000000000000, 0x8000000000000000) 23 | NEG(8, 0x7fffffffffffffff, 0x8000000000000001) 24 | #endif 25 | 26 | #undef NEG 27 | #define NEG(N, T, I, V) FUN(N, T, neg, I, V) 28 | NEG(0, _f, 0.0, -0.0) 29 | NEG(1, _f, 0.5, -0.5) 30 | NEG(2, _f, $(1 / 0.0), $(-1.0 / 0)) 31 | NEG(3, _f, -1.25, 1.25) 32 | NEG(0, _d, 0.0, -0.0) 33 | NEG(1, _d, 0.5, -0.5) 34 | NEG(2, _d, $(1.0 / 0), $(-1 / 0.0)) 35 | NEG(3, _d, -1.25, 1.25) 36 | 37 | prepare 38 | pushargi ok 39 | ellipsis 40 | finishi @printf 41 | ret 42 | epilog 43 | -------------------------------------------------------------------------------- /lightning/check/alu_or.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_or.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define OR(N, I0, I1, V) ALU(N, , or, I0, I1, V) 7 | 8 | OR(0, 0x7fffffff, 1, 0x7fffffff) 9 | OR(1, 1, 0x7fffffff, 0x7fffffff) 10 | OR(2, 0x80000000, 1, 0x80000001) 11 | OR(3, 1, 0x80000000, 0x80000001) 12 | OR(4, 0x7fffffff, 0x80000000, 0xffffffff) 13 | OR(5, 0x80000000, 0x7fffffff, 0xffffffff) 14 | OR(6, 0x7fffffff, 0xffffffff, 0xffffffff) 15 | OR(7, 0xffffffff, 0x7fffffff, 0xffffffff) 16 | OR(8, 0xffffffff, 0xffffffff, 0xffffffff) 17 | OR(9, 0x7fffffff, 0, 0x7fffffff) 18 | OR(10, 0, 0x7fffffff, 0x7fffffff) 19 | #if __WORDSIZE == 64 20 | OR(11, 0x7fffffffffffffff, 1, 0x7fffffffffffffff) 21 | OR(12, 1, 0x7fffffffffffffff, 0x7fffffffffffffff) 22 | OR(13, 0x8000000000000000, 1, 0x8000000000000001) 23 | OR(14, 1, 0x8000000000000000, 0x8000000000000001) 24 | OR(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) 25 | OR(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 26 | OR(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) 27 | OR(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff) 28 | OR(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff) 29 | #endif 30 | 31 | prepare 32 | pushargi ok 33 | ellipsis 34 | finishi @printf 35 | ret 36 | epilog 37 | -------------------------------------------------------------------------------- /lightning/check/alu_rem.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_rem.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define REM(N, I0, I1, V) ALU(N, , rem, I0, I1, V) 7 | #define UREM(N, I0, I1, V) ALU(N, _u, rem, I0, I1, V) 8 | 9 | REM(0, 0x7fffffff, 1, 0) 10 | REM(1, 1, 0x7fffffff, 1) 11 | REM(2, 0x80000000, 1, 0) 12 | REM(3, 1, 0x80000000, 1) 13 | REM(4, 0x7fffffff, 2, 1) 14 | REM(5, 2, 0x7fffffff, 2) 15 | REM(6, 0x80000000, 2, 0) 16 | REM(7, 2, 0x80000000, 2) 17 | REM(8, 0x7fffffff, 0x80000000, 0x7fffffff) 18 | REM(9, 0, 0x7fffffff, 0) 19 | REM(10, 0xffffffff, 0xffffffff, 0) 20 | UREM(0, 0x7fffffff, 1, 0) 21 | UREM(1, 1, 0x7fffffff, 1) 22 | UREM(2, 0x80000000, 1, 0) 23 | UREM(3, 1, 0x80000000, 1) 24 | UREM(4, 0x7fffffff, 2, 1) 25 | UREM(5, 2, 0x7fffffff, 2) 26 | UREM(6, 0x80000000, 2, 0) 27 | UREM(7, 2, 0x80000000, 2) 28 | UREM(8, 0x7fffffff, 0x80000000, 0x7fffffff) 29 | UREM(9, 0x80000000, 0x7fffffff, 1) 30 | UREM(10,0, 0x7fffffff, 0) 31 | UREM(11,0x7fffffff, 0xffffffff, 0x7fffffff) 32 | UREM(12,0xffffffff, 0x7fffffff, 1) 33 | UREM(13,0xffffffff, 0xffffffff, 0) 34 | 35 | #if __WORDSIZE == 32 36 | REM(11, 0x80000000, 0x7fffffff, 0xffffffff) 37 | REM(12, 0x7fffffff, 0xffffffff, 0) 38 | REM(13, 0xffffffff, 0x7fffffff, 0xffffffff) 39 | #else 40 | REM(11, 0x80000000, 0x7fffffff, 1) 41 | REM(12, 0x7fffffff, 0xffffffff, 0x7fffffff) 42 | REM(13, 0xffffffff, 0x7fffffff, 1) 43 | REM(14, 0x7fffffffffffffff, 1, 0) 44 | REM(15, 1, 0x7fffffffffffffff, 1) 45 | REM(16, 0x8000000000000000, 1, 0) 46 | REM(17, 1, 0x8000000000000000, 1) 47 | REM(18, 0x7fffffffffffffff, 2, 1) 48 | REM(19, 2, 0x7fffffffffffffff, 2) 49 | REM(20, 0x8000000000000000, 2, 0) 50 | REM(21, 2, 0x8000000000000000, 2) 51 | REM(22, 0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff) 52 | REM(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 53 | REM(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0) 54 | REM(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff) 55 | REM(26, 0xffffffffffffffff, 0xffffffffffffffff, 0) 56 | UREM(14,0x7fffffffffffffff, 1, 0) 57 | UREM(15,1, 0x7fffffffffffffff, 1) 58 | UREM(16,0x8000000000000000, 1, 0) 59 | UREM(17,1, 0x8000000000000000, 1) 60 | UREM(18,0x7fffffffffffffff, 2, 1) 61 | UREM(19,2, 0x7fffffffffffffff, 2) 62 | UREM(20,0x8000000000000000, 2, 0) 63 | UREM(21,2, 0x8000000000000000, 2) 64 | UREM(22,0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff) 65 | UREM(23,0x8000000000000000, 0x7fffffffffffffff, 1) 66 | UREM(24,0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff) 67 | UREM(25,0xffffffffffffffff, 0x7fffffffffffffff, 1) 68 | UREM(26,0xffffffffffffffff, 0xffffffffffffffff, 0) 69 | #endif 70 | 71 | prepare 72 | pushargi ok 73 | ellipsis 74 | finishi @printf 75 | ret 76 | epilog 77 | -------------------------------------------------------------------------------- /lightning/check/alu_rsb.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_rsb.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define RSB(N, I0, I1, V) ALU(N, , rsb, I0, I1, V) 7 | 8 | RSB(0, 1, 0x7fffffff, 0x7ffffffe) 9 | RSB(2, 1, 0x80000000, 0x7fffffff) 10 | RSB(3, 0x7fffffff, 0x80000000, 1) 11 | RSB(4, 0xffffffff, 0xffffffff, 0) 12 | RSB(5, 0x7fffffff, 0xffffffff, 0x80000000) 13 | RSB(6, 0, 0x7fffffff, 0x7fffffff) 14 | #if __WORDSIZE == 32 15 | RSB(7, 0x7fffffff, 1, 0x80000002) 16 | RSB(8, 0x80000000, 1, 0x80000001) 17 | RSB(9, 0x80000000, 0x7fffffff, 0xffffffff) 18 | RSB(10, 0xffffffff, 0x7fffffff, 0x80000000) 19 | RSB(11, 0x7fffffff, 0, 0x80000001) 20 | #else 21 | RSB(7, 0x7fffffff, 1, 0xffffffff80000002) 22 | RSB(8, 0xffffffff80000000, 1, 0x80000001) 23 | RSB(9, 0xffffffff80000000, 0x7fffffff, 0xffffffff) 24 | RSB(10, 0xffffffffffffffff, 0xffffffff7fffffff, 0xffffffff80000000) 25 | RSB(11, 0x7fffffff, 0, 0xffffffff80000001) 26 | RSB(12, 1, 0x7fffffffffffffff, 0x7ffffffffffffffe) 27 | RSB(13, 0x7fffffffffffffff, 1, 0x8000000000000002) 28 | RSB(14, 1, 0x8000000000000000, 0x7fffffffffffffff) 29 | RSB(15, 0x8000000000000000, 1, 0x8000000000000001) 30 | RSB(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 31 | RSB(17, 0x7fffffffffffffff, 0x8000000000000000, 1) 32 | RSB(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) 33 | RSB(19, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) 34 | RSB(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) 35 | #endif 36 | 37 | #undef RSB 38 | #define RSB(N, T, I0, I1, V) FOP(N, T, rsb, I0, I1, V) 39 | RSB(0, _f, 0.5, -0.5, -1.0) 40 | RSB(1, _f, 0.75, 0.25, -0.5) 41 | RSB(0, _d, 0.5, -0.5, -1.0) 42 | RSB(1, _d, 0.75, 0.25, -0.5) 43 | 44 | prepare 45 | pushargi ok 46 | ellipsis 47 | finishi @printf 48 | ret 49 | epilog 50 | -------------------------------------------------------------------------------- /lightning/check/alu_rsh.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_rsh.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define RSH(N, I0, I1, V) ALU(N, , rsh, I0, I1, V) 7 | #define URSH(N, I0, I1, V) ALU(N, _u, rsh, I0, I1, V) 8 | 9 | RSH(0, 0xfe, 1, 0x7f) 10 | RSH(1, 0x1fffc, 2, 0x7fff) 11 | RSH(2, 0x40000000, 30, 1) 12 | RSH(3, 0x20000000, 29, 1) 13 | RSH(4, 0x10000000, 28, 1) 14 | RSH(5, 0x810000, 16, 0x81) 15 | RSH(6, 0x20000, 17, 1) 16 | RSH(7, 0x40000, 18, 1) 17 | RSH(8, 0x7f8000, 15, 0xff) 18 | RSH(9, 0x1000000, 24, 1) 19 | RSH(10, 0x7fffffff, 0, 0x7fffffff) 20 | URSH(0, 0xfe, 1, 0x7f) 21 | URSH(1, 0x1fffc, 2, 0x7fff) 22 | URSH(2, 0x80000000, 31, 1) 23 | URSH(3, 0x40000000, 30, 1) 24 | URSH(4, 0x20000000, 29, 1) 25 | URSH(5, 0x10000000, 28, 1) 26 | URSH(6, 0x810000, 16, 0x81) 27 | URSH(7, 0x20000, 17, 1) 28 | URSH(8, 0x40000, 18, 1) 29 | URSH(9,0x7f8000, 15, 0xff) 30 | URSH(10,0x1000000, 24, 1) 31 | URSH(11,0xffffff00, 8, 0xffffff) 32 | URSH(12,0x7fffffff, 0, 0x7fffffff) 33 | #if __WORDSIZE == 32 34 | RSH(11, 0xfffffff8, 3, 0xffffffff) 35 | RSH(12, 0x80000000, 31, 0xffffffff) 36 | RSH(13, 0xffffff00, 8, 0xffffffff) 37 | URSH(13,0xfffffff8, 3, 0x1fffffff) 38 | #else 39 | RSH(11, 0x3fffffff8, 3, 0x7fffffff) 40 | RSH(12, 0xffffffc080000000, 31, 0xffffffffffffff81) 41 | RSH(13, 0xffffff00, 8, 0xffffff) 42 | RSH(14, 0xfe00000000, 33, 0x7f) 43 | RSH(15, 0x1ffffc00000000, 34, 0x7ffff) 44 | RSH(16, 0xfffffff800000000, 29, 0xffffffffffffffc0) 45 | RSH(17, 0x8000000000000000, 63, 0xffffffffffffffff) 46 | RSH(18, 0x4000000000000000, 62, 1) 47 | RSH(19, 0x2000000000000000, 61, 1) 48 | RSH(20, 0x1000000000000000, 60, 1) 49 | RSH(21, 0x81000000000000, 48, 0x81) 50 | RSH(22, 0x2000000000000, 49, 1) 51 | RSH(23, 0x10000000000, 40, 1) 52 | RSH(24, 0x7f800000000000, 47, 0xff) 53 | RSH(25, 0x100000000000000, 56, 1) 54 | RSH(26, 0xffffff0000000000, 40, 0xffffffffffffffff) 55 | RSH(27, 0xfffffffe00000000, 33, 0xffffffffffffffff) 56 | RSH(28, 0x8000000000000001, 63, 0xffffffffffffffff) 57 | RSH(29, 0x1000000000000, 48, 1) 58 | RSH(30, 0xffff800000000000, 47, 0xffffffffffffffff) 59 | URSH(13,0x3fffffff8, 3, 0x7fffffff) 60 | URSH(14,0xffffffc080000000, 31, 0x1ffffff81) 61 | URSH(15,0xfe00000000, 33, 0x7f) 62 | URSH(16,0x1ffffc00000000, 34, 0x7ffff) 63 | URSH(17,0xfffffff800000000, 29, 0x7ffffffc0) 64 | URSH(18,0x8000000000000000, 63, 1) 65 | URSH(19,0x4000000000000000, 62, 1) 66 | URSH(20,0x2000000000000000, 61, 1) 67 | URSH(21,0x1000000000000000, 60, 1) 68 | URSH(22,0x81000000000000, 48, 0x81) 69 | URSH(23,0x2000000000000, 49, 1) 70 | URSH(24,0x10000000000, 40, 1) 71 | URSH(25,0x7f800000000000, 47, 0xff) 72 | URSH(26,0x100000000000000, 56, 1) 73 | URSH(27,0xffffff0000000000, 40, 0xffffff) 74 | URSH(28,0xfffffffe00000000, 33, 0x7fffffff) 75 | URSH(29,0x8000000000000001, 63, 1) 76 | URSH(30,0x1000000000000, 48, 1) 77 | URSH(31,0xffff800000000000, 47, 0x1ffff) 78 | #endif 79 | 80 | prepare 81 | pushargi ok 82 | ellipsis 83 | finishi @printf 84 | ret 85 | epilog 86 | -------------------------------------------------------------------------------- /lightning/check/alu_sub.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_sub.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define SUB(N, I0, I1, V) ALU(N, , sub, I0, I1, V) 7 | 8 | SUB(0, 0x7fffffff, 1, 0x7ffffffe) 9 | SUB(2, 0x80000000, 1, 0x7fffffff) 10 | SUB(3, 0x80000000, 0x7fffffff, 1) 11 | SUB(4, 0xffffffff, 0xffffffff, 0) 12 | SUB(5, 0xffffffff, 0x7fffffff, 0x80000000) 13 | SUB(6, 0x7fffffff, 0, 0x7fffffff) 14 | #if __WORDSIZE == 32 15 | SUB(7, 1, 0x7fffffff, 0x80000002) 16 | SUB(8, 1, 0x80000000, 0x80000001) 17 | SUB(9, 0x7fffffff, 0x80000000, 0xffffffff) 18 | SUB(10, 0x7fffffff, 0xffffffff, 0x80000000) 19 | SUB(11, 0, 0x7fffffff, 0x80000001) 20 | #else 21 | SUB(7, 1, 0x7fffffff, 0xffffffff80000002) 22 | SUB(8, 1, 0xffffffff80000000, 0x80000001) 23 | SUB(9, 0x7fffffff, 0xffffffff80000000, 0xffffffff) 24 | SUB(10, 0xffffffff7fffffff, 0xffffffffffffffff, 0xffffffff80000000) 25 | SUB(11, 0, 0x7fffffff, 0xffffffff80000001) 26 | SUB(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe) 27 | SUB(13, 1, 0x7fffffffffffffff, 0x8000000000000002) 28 | SUB(14, 0x8000000000000000, 1, 0x7fffffffffffffff) 29 | SUB(15, 1, 0x8000000000000000, 0x8000000000000001) 30 | SUB(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) 31 | SUB(17, 0x8000000000000000, 0x7fffffffffffffff, 1) 32 | SUB(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) 33 | SUB(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) 34 | SUB(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) 35 | #endif 36 | 37 | #undef SUB 38 | #define SUB(N, T, I0, I1, V) FOP(N, T, sub, I0, I1, V) 39 | SUB(0, _f, -0.5, 0.5, -1.0) 40 | SUB(1, _f, 0.25, 0.75, -0.5) 41 | SUB(0, _d, -0.5, 0.5, -1.0) 42 | SUB(1, _d, 0.25, 0.75, -0.5) 43 | 44 | prepare 45 | pushargi ok 46 | ellipsis 47 | finishi @printf 48 | ret 49 | epilog 50 | -------------------------------------------------------------------------------- /lightning/check/alu_xor.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alu_xor.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define XOR(N, I0, I1, V) ALU(N, , xor, I0, I1, V) 7 | 8 | XOR(0, 0x7fffffff, 1, 0x7ffffffe) 9 | XOR(1, 1, 0x7fffffff, 0x7ffffffe) 10 | XOR(2, 0x80000000, 1, 0x80000001) 11 | XOR(3, 1, 0x80000000, 0x80000001) 12 | XOR(4, 0x7fffffff, 0x80000000, 0xffffffff) 13 | XOR(5, 0x80000000, 0x7fffffff, 0xffffffff) 14 | XOR(6, 0x7fffffff, 0xffffffff, 0x80000000) 15 | XOR(7, 0xffffffff, 0x7fffffff, 0x80000000) 16 | XOR(9, 0xffffffff, 0xffffffff, 0) 17 | XOR(10, 0x7fffffff, 0, 0x7fffffff) 18 | XOR(11, 0, 0x7fffffff, 0x7fffffff) 19 | #if __WORDSIZE == 64 20 | XOR(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe) 21 | XOR(13, 1, 0x7fffffffffffffff, 0x7ffffffffffffffe) 22 | XOR(14, 0x8000000000000000, 1, 0x8000000000000001) 23 | XOR(15, 1, 0x8000000000000000, 0x8000000000000001) 24 | XOR(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff) 25 | XOR(17, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff) 26 | XOR(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000) 27 | XOR(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000) 28 | XOR(20, 0xffffffffffffffff, 0xffffffffffffffff, 0) 29 | #endif 30 | 31 | prepare 32 | pushargi ok 33 | ellipsis 34 | finishi @printf 35 | ret 36 | epilog 37 | -------------------------------------------------------------------------------- /lightning/check/alux_add.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alux_add.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define ADDX(N, I0, I1, V) ALUX(N, add, I0, I1, V) 7 | 8 | /* nothing */ 9 | ADDX(0, 0, 0, 0) 10 | #if __WORDSIZE == 32 11 | /* carry */ 12 | ADDX(1, 0xffffffff, 0xffffffff, 1) 13 | /* overflow */ 14 | ADDX(2, 0x7fffffff, 1, 0) 15 | /* overflow */ 16 | ADDX(3, 0x7fffffff, 0x7fffffff, 0) 17 | /* carry */ 18 | ADDX(4, 0x7fffffff, 0x80000000, 0) 19 | /* carry+overflow */ 20 | ADDX(5, 0x80000000, 0x80000000, 1) 21 | #else 22 | /* nothing */ 23 | ADDX(1, 0xffffffff, 0xffffffff, 0) 24 | /* nothing */ 25 | ADDX(2, 0x7fffffff, 1, 0) 26 | /* nothing */ 27 | ADDX(3, 0x7fffffff, 0x7fffffff, 0) 28 | /* nothing */ 29 | ADDX(4, 0x7fffffff, 0x80000000, 0) 30 | /* nothing */ 31 | ADDX(5, 0x80000000, 0x80000000, 0) 32 | /* carry */ 33 | ADDX(6, 0xffffffffffffffff, 0xffffffffffffffff, 1) 34 | /* overflow */ 35 | ADDX(7, 0x7fffffffffffffff, 1, 0) 36 | /* overflow */ 37 | ADDX(8, 0x7fffffffffffffff, 0x7fffffffffffffff, 0) 38 | /* overflow */ 39 | ADDX(9, 0x7fffffffffffffff, 0x8000000000000000, 0) 40 | /* carry+overflow */ 41 | ADDX(10,0x8000000000000000, 0x8000000000000000, 1) 42 | #endif 43 | 44 | prepare 45 | pushargi ok 46 | ellipsis 47 | finishi @printf 48 | ret 49 | epilog 50 | -------------------------------------------------------------------------------- /lightning/check/alux_sub.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/alux_sub.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | 6 | #define SUBX(N, I0, I1, V) ALUX(N, sub, I0, I1, V) 7 | 8 | /* nothing */ 9 | SUBX(0, 0, 0, 0) 10 | #if __WORDSIZE == 32 11 | /* carry */ 12 | SUBX(1, 0x7fffffff, 0xffffffff, 0xffffffff) 13 | /* overflow */ 14 | SUBX(2, 0x80000000, 1, 0) 15 | /* carry */ 16 | SUBX(3, 0x7fffffff, 0x80000000, 0xffffffff) 17 | /* overflow */ 18 | SUBX(4, 0x80000000, 0x7fffffff, 0) 19 | /* carry+overflow */ 20 | SUBX(5, 1, 0x80000000, 0xffffffff) 21 | #else 22 | /* carry */ 23 | SUBX(1, 0x7fffffff, 0xffffffff, -1) 24 | /* nothing */ 25 | SUBX(2, 0x80000000, 1, 0) 26 | /* carry */ 27 | SUBX(3, 0x7fffffff, 0x80000000, -1) 28 | /* nothing */ 29 | SUBX(4, 0x80000000, 0x7fffffff, 0) 30 | /* carry */ 31 | SUBX(5, 1, 0x80000000, -1) 32 | /* carry */ 33 | SUBX(6, 0x7fffffffffffffff, 0xffffffffffffffff, -1) 34 | /* overflow */ 35 | SUBX(7, 0x8000000000000000, 1, 0) 36 | /* carry */ 37 | SUBX(8, 0x7fffffffffffffff, 0x8000000000000000, -1) 38 | /* overflow */ 39 | SUBX(9, 0x8000000000000000, 0x7fffffffffffffff, 0) 40 | /* carry+overflow */ 41 | SUBX(10,1, 0x8000000000000000, -1) 42 | #endif 43 | 44 | prepare 45 | pushargi ok 46 | ellipsis 47 | finishi @printf 48 | ret 49 | epilog 50 | -------------------------------------------------------------------------------- /lightning/check/bit.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/bp.ok: -------------------------------------------------------------------------------- 1 | nfibs(32) = 2178309 2 | -------------------------------------------------------------------------------- /lightning/check/bp.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | fmt: 3 | .c "nfibs(%d) = %d\n" 4 | 5 | .code 6 | jmpi main 7 | 8 | name rfibs 9 | rfibs: 10 | prolog 11 | arg $in 12 | getarg %r0 $in /* R0 = N */ 13 | beqi out %r0 0 14 | movr %v0 %r0 /* V0 = R0 */ 15 | movi %r0 1 16 | blei_u out %v0 2 17 | subi %v1 %v0 1 /* V1 = N-1 */ 18 | subi %v2 %v0 2 /* V1 = N-2 */ 19 | prepare 20 | pushargr %v1 21 | finishi rfibs 22 | retval %v1 /* V1 = rfibs(N-1) */ 23 | prepare 24 | pushargr %v2 25 | finishi rfibs 26 | retval %r0 /* R0 = rfibs(N-2) */ 27 | addr %r0 %r0 %v1 28 | out: 29 | retr %r0 30 | epilog 31 | 32 | name main 33 | main: 34 | prolog 35 | prepare 36 | pushargi 32 37 | finishi rfibs 38 | retval %v0 39 | prepare 40 | pushargi fmt 41 | ellipsis 42 | pushargi 32 43 | pushargr %v0 44 | finishi @printf 45 | ret 46 | epilog 47 | -------------------------------------------------------------------------------- /lightning/check/branch.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/bswap.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/call.ok: -------------------------------------------------------------------------------- 1 | forward 2 | backward 3 | forward 4 | backward 5 | -------------------------------------------------------------------------------- /lightning/check/carry.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/catomic.ok: -------------------------------------------------------------------------------- 1 | ok 2 | ok 3 | ok 4 | ok 5 | ok 6 | -------------------------------------------------------------------------------- /lightning/check/check.arm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.arm$||'` 3 | ./lightning -mthumb=0 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.arm.swf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.arm\.swf$||'` 3 | ./lightning -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.arm4.swf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.arm4\.swf$||'` 3 | ./lightning -mcpu=4 -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.nodata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.nodata$||'` 3 | ./lightning -d $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0` 3 | ./lightning $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.swf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.swf$||'` 3 | ./lightning -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.x87.nodata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.x87.nodata$||'` 3 | ./lightning -data=0 -mx87=1 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/check.x87.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test=`basename $0 | sed -e 's|\.x87$||'` 3 | ./lightning -mx87=1 $srcdir/$test.tst | tr -d \\r > $test.out 4 | if test $? != 0; then 5 | exit $? 6 | fi 7 | 8 | cmp -s $srcdir/$test.ok $test.out 9 | result=$? 10 | if test $result != 0; then 11 | diff $srcdir/$test.ok $test.out 12 | rm $test.out 13 | exit 1 14 | fi 15 | rm $test.out 16 | -------------------------------------------------------------------------------- /lightning/check/clobber.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/collatz.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | str: 3 | .c "%lu\n" 4 | .code 5 | jmpi main 6 | /* 7 | * unsigned long collatz(unsigned long n) { 8 | * unsigned long r = n; 9 | * if (!(r & 1)) { 10 | * r = r / 2; 11 | * return r; 12 | * } 13 | * r = r * 3; 14 | * r = r + 1; 15 | * return r; 16 | * } 17 | */ 18 | collatz: 19 | prolog 20 | arg $n 21 | getarg %r0 $n 22 | bmsi odd %r0 1 23 | //divi_u %r0 %r0 2 24 | rshi_u %r0 %r0 1 25 | retr %r0 26 | odd: 27 | muli %r0 %r0 3 28 | addi %r0 %r0 1 29 | retr %r0 30 | epilog 31 | 32 | /* 33 | * int main(int argc, char *argv[]) { 34 | * unsigned long v; 35 | * if (argc == 2) 36 | * v = strtoul(argv[1], NULL, 0); 37 | * else 38 | * v = (1L << __WORDSIZE / 2) - 1; 39 | * while (1) { 40 | * printf("%ld\n", v); 41 | * if (v <= 1) 42 | * break; 43 | * v = collatz(v); 44 | * } 45 | * return 0; 46 | * } 47 | */ 48 | main: 49 | prolog 50 | arg $argc 51 | arg $argv 52 | getarg %r0 $argc 53 | bnei default %r0 2 54 | getarg %v0 $argv 55 | ldxi %r0 %v0 $(__WORDSIZE >> 3) 56 | prepare 57 | pushargr %r0 58 | pushargi 0 59 | pushargi 0 60 | finishi @strtoul 61 | retval %v0 62 | jmpi loop 63 | default: 64 | movi %v0 $((1 << __WORDSIZE / 2) - 1) 65 | loop: 66 | prepare 67 | pushargi str 68 | ellipsis 69 | pushargr %v0 70 | finishi @printf 71 | blei_u done %v0 1 72 | prepare 73 | pushargr %v0 74 | finishi collatz 75 | retval %v0 76 | jmpi loop 77 | done: 78 | reti 0 79 | epilog 80 | -------------------------------------------------------------------------------- /lightning/check/cvt.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/divi.ok: -------------------------------------------------------------------------------- 1 | 40/8 = 5 (expected 5) 2 | 64/8 = 8 (expected 8) 3 | 80/8 = 10 (expected 10) 4 | 98304/32768 = 3 (expected 3) 5 | 65536/32768 = 2 (expected 2) 6 | 163840/32768 = 5 (expected 5) 7 | -------------------------------------------------------------------------------- /lightning/check/divi.tst: -------------------------------------------------------------------------------- 1 | .data 128 2 | small_ops: 3 | .i 40 64 80 4 | large_ops: 5 | .i 98304 65536 163840 6 | fmt: 7 | .c "%i/%i = %i (expected %i)\n" 8 | x: 9 | .c "%d\n" 10 | .code 11 | jmpi main 12 | 13 | #define generate_divider(operand) \ 14 | name divider_##operand \ 15 | divider_##operand: \ 16 | prolog \ 17 | arg $i \ 18 | getarg %r1 $i \ 19 | divi %r2 %r1 operand \ 20 | retr %r2 \ 21 | epilog 22 | generate_divider(8) 23 | generate_divider(32768) 24 | 25 | #define generate_test_divider(divisor) \ 26 | name test_divider_##divisor \ 27 | test_divider_##divisor: \ 28 | prolog \ 29 | allocai 4 $loc \ 30 | arg $p \ 31 | arg $c \ 32 | getarg %v0 $p \ 33 | getarg %v1 $c \ 34 | muli %v1 %v1 4 \ 35 | addr %v1 %v0 %v1 \ 36 | loop_##divisor: \ 37 | bger done_##divisor %v0 %v1 \ 38 | ldr_i %v2 %v0 \ 39 | prepare \ 40 | pushargr %v2 \ 41 | finishi divider_##divisor \ 42 | retval %v2 \ 43 | ldr_i %r2 %v0 \ 44 | divi %r0 %r2 divisor \ 45 | /* save div result */ \ 46 | stxi_i $loc %fp %r0 \ 47 | prepare \ 48 | pushargi fmt \ 49 | ellipsis \ 50 | pushargr %r2 \ 51 | pushargi divisor \ 52 | pushargr %v2 \ 53 | pushargr %r0 \ 54 | finishi @printf \ 55 | addi %v0 %v0 4 \ 56 | /* reload div result */ \ 57 | ldxi_i %r0 %fp $loc \ 58 | beqr loop_##divisor %r0 %v2 \ 59 | /* return if failed */ \ 60 | reti 1 \ 61 | done_##divisor: \ 62 | reti 0 \ 63 | epilog 64 | generate_test_divider(8) 65 | generate_test_divider(32768) 66 | 67 | name main 68 | main: 69 | prolog 70 | prepare 71 | pushargi small_ops 72 | pushargi 3 73 | finishi test_divider_8 74 | retval %r0 75 | bnei fail %r0 0 76 | prepare 77 | pushargi large_ops 78 | pushargi 3 79 | finishi test_divider_32768 80 | retval %r0 81 | bnei fail %r0 0 82 | reti 0 83 | fail: 84 | reti 1 85 | epilog 86 | -------------------------------------------------------------------------------- /lightning/check/factorial.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | str: 3 | .c "%.0lf\n" 4 | .code 5 | jmpi main 6 | /* 7 | * double factorial(unsigned long n) { 8 | * double r = 1; 9 | * while (n > 1) { 10 | * r *= n; 11 | * --n; 12 | * } 13 | * return r; 14 | * } 15 | */ 16 | factorial: 17 | prolog 18 | arg $n 19 | getarg %r0 $n 20 | movi_d %f0 1.0 21 | extr_d %f1 %r0 22 | movr_d %f2 %f0 23 | loop: 24 | bltr_d done %f1 %f2 25 | mulr_d %f0 %f0 %f1 26 | subr_d %f1 %f1 %f2 27 | jmpi loop 28 | done: 29 | retr_d %f0 30 | epilog 31 | 32 | /* 33 | * int main(int argc, char *argv[]) { 34 | * unsigned long v; 35 | * double d; 36 | * if (argc == 2) 37 | * v = strtoul(argv[1], NULL, 0); 38 | * else 39 | * v = 32; 40 | * d = factorial(v); 41 | * printf("%.0lf\n", d); 42 | * return 0; 43 | * } 44 | */ 45 | main: 46 | prolog 47 | arg $argc 48 | arg $argv 49 | getarg %r0 $argc 50 | bnei default %r0 2 51 | getarg %v0 $argv 52 | ldxi %r0 %v0 $(__WORDSIZE >> 3) 53 | prepare 54 | pushargr %r0 55 | pushargi 0 56 | pushargi 0 57 | finishi @strtoul 58 | retval %v0 59 | jmpi call 60 | default: 61 | movi %v0 32 62 | call: 63 | prepare 64 | pushargr %v0 65 | finishi factorial 66 | retval_d %f0 67 | prepare 68 | pushargi str 69 | ellipsis 70 | pushargr_d %f0 71 | finishi @printf 72 | reti 0 73 | epilog 74 | -------------------------------------------------------------------------------- /lightning/check/fib.ok: -------------------------------------------------------------------------------- 1 | nfibs(32) = 2178309 2 | -------------------------------------------------------------------------------- /lightning/check/fib.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | format: 3 | .c "nfibs(%d) = %d\n" 4 | 5 | .code 6 | jmpi main 7 | 8 | name nfibs 9 | nfibs: 10 | prolog 11 | arg $in 12 | getarg %r0 $in // R0 = n 13 | beqi ref %r0 0 14 | movr %r1 %r0 15 | movi %r0 1 16 | blei_u ref %r1 2 17 | subi %r2 %r1 2 18 | movr %r1 %r0 19 | loop: 20 | subi %r2 %r2 1 // decr. counter 21 | movr %v0 %r0 // V0 = R0 22 | addr %r0 %r0 %r1 // R0 = R0 + R1 23 | movr %r1 %v0 // R1 = V0 24 | bnei loop %r2 0 // if (R2) goto loop 25 | ref: 26 | retr %r0 // RET = R0 27 | epilog 28 | 29 | name main 30 | main: 31 | prolog 32 | arg $argc 33 | arg $argv 34 | 35 | getarg %r0 $argc 36 | blei default %r0 1 37 | getarg %r0 $argv 38 | addi %r0 %r0 $(__WORDSIZE >> 3) 39 | ldr %r0 %r0 40 | prepare 41 | pushargr %r0 42 | finishi @atoi 43 | retval %r0 44 | jmpi call 45 | 46 | default: 47 | movi %r0 32 48 | 49 | call: 50 | movr %v0 %r0 51 | prepare 52 | pushargr %r0 53 | finishi nfibs 54 | retval %r0 55 | prepare 56 | pushargi format 57 | ellipsis 58 | pushargr %v0 59 | pushargr %r0 60 | finishi @printf 61 | ret 62 | epilog 63 | -------------------------------------------------------------------------------- /lightning/check/float.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/fop_abs.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/fop_abs.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | #define ABS(N, T, I, V) FUN(N, T, abs, I, V) 6 | #define UABS(N, T, I, V) UFUN(N, T, abs, I, V) 7 | ABS(0, _f, -0.0, 0.0) 8 | ABS(1, _f, 0.5, 0.5) 9 | ABS(2, _f, -0.5, 0.5) 10 | ABS(3, _f, $Inf, $Inf) 11 | ABS(4, _f, $nInf, $Inf) 12 | ABS(5, _f, 1.25, 1.25) 13 | ABS(6, _f, -1.25, 1.25) 14 | ABS(7, _f, $nInf, $Inf) 15 | UABS(0, _f, $NaN, $NaN) 16 | ABS(0, _d, -0.0, 0.0) 17 | ABS(1, _d, 0.5, 0.5) 18 | ABS(2, _d, -0.5, 0.5) 19 | ABS(3, _d, $Inf, $Inf) 20 | ABS(4, _d, $nInf, $Inf) 21 | ABS(5, _d, 1.25, 1.25) 22 | ABS(6, _d, -1.25, 1.25) 23 | ABS(7, _d, $nInf, $Inf) 24 | UABS(0, _d, $NaN, $NaN) 25 | 26 | prepare 27 | pushargi ok 28 | ellipsis 29 | finishi @printf 30 | ret 31 | epilog 32 | -------------------------------------------------------------------------------- /lightning/check/fop_sqrt.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/fop_sqrt.tst: -------------------------------------------------------------------------------- 1 | #include "alu.inc" 2 | 3 | .code 4 | prolog 5 | #define SQRT(N, T, I, V) FUN(N, T, sqrt, I, V) 6 | #define USQRT(N, T, I, V) UFUN(N, T, sqrt, I, V) 7 | SQRT(0, _f, -0.0, 0.0) 8 | SQRT(1, _f, 4.0, 2.0) 9 | SQRT(2, _f, 2.25, 1.5) 10 | SQRT(3, _f, $Inf, $Inf) 11 | USQRT(0, _f, $NaN, $NaN) 12 | SQRT(0, _d, -0.0, 0.0) 13 | SQRT(1, _d, 4.0, 2.0) 14 | SQRT(2, _d, 2.25, 1.5) 15 | SQRT(3, _d, $Inf, $Inf) 16 | USQRT(0, _d, $NaN, $NaN) 17 | 18 | prepare 19 | pushargi ok 20 | ellipsis 21 | finishi @printf 22 | ret 23 | epilog 24 | -------------------------------------------------------------------------------- /lightning/check/hton.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/jmpr.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/jmpr.tst: -------------------------------------------------------------------------------- 1 | /* 2 | This is a very simple check to a condition that on lightning 2.0.5 3 | could cause an assertion on some backends, due to correcting a problem 4 | with temporaries that could not be saved/reloaded due to being used only 5 | in the hardware instruction, or being considered live for too long on the 6 | lightning instruction, and that could not be reloaded after the jump target 7 | (or after false/true target on conditional branches). 8 | 9 | If this code in lib/lightning.c:_jit_update(): 10 | 11 | for (regno = 0; regno < _jitc->reglen; regno++) { 12 | spec = jit_class(_rvs[regno].spec); 13 | if (jit_regset_tstbit(mask, regno) && 14 | (spec & (jit_class_gpr|jit_class_fpr)) && 15 | !(spec & jit_class_sav)) 16 | jit_regset_clrbit(mask, regno); 17 | } 18 | 19 | were removed, this test case, on x86_64 would fail like this: 20 | 21 | lt-lightning: lightning.c:305: _jit_get_reg: Assertion `regspec & 0x02000000' failed. 22 | Aborted (core dumped) 23 | */ 24 | 25 | .data 32 26 | ret: 27 | #if __WORDSIZE == 32 28 | .i 0 29 | #else 30 | .l 0 31 | #endif 32 | ok: 33 | .c "ok" 34 | 35 | .code 36 | prolog 37 | jmpi start 38 | 39 | add_v1_v2: 40 | addr %v1 %v1 %v2 41 | ldi %r0 ret 42 | jmpr %r0 43 | 44 | start: 45 | movi %v1 1 46 | movi %v2 2 47 | movi %r0 ret_add_v1_v2 48 | sti ret %r0 49 | movi %v0 add_v1_v2 50 | jmpr %v0 51 | movi_d %f0 3 52 | beqi_d pass_movi_f0 %f0 3 53 | calli @abort 54 | pass_movi_f0: 55 | beqi pass_check_v2 %v2 2 56 | calli @abort 57 | pass_check_v2: 58 | ret_add_v1_v2: 59 | beqi pass_add_v1_v2 %v1 3 60 | calli @abort 61 | pass_add_v1_v2: 62 | prepare 63 | pushargi ok 64 | finishi @puts 65 | ret 66 | epilog 67 | -------------------------------------------------------------------------------- /lightning/check/ldst.inc: -------------------------------------------------------------------------------- 1 | #if __WORDSIZE == 64 2 | # define L0 0x8000000000000001 3 | # define LL0 L0 4 | # define LC0 0xffffffffffffff81 5 | # define LS0 0xffffffffffff8001 6 | # define LI0 0xffffffff80000001 7 | # define L1 0x8000000000000000 8 | # define LL1 L1 9 | # define LC1 0xffffffffffffff80 10 | # define LS1 0xffffffffffff8000 11 | # define LI1 0xffffffff80000000 12 | # define L2 0x7fffffffffffffff 13 | # define LL2 L2 14 | # define LC2 0x000000000000007f 15 | # define LS2 0x0000000000007fff 16 | # define LI2 0x000000007fffffff 17 | # define L3 0xffffffffffffffff 18 | # define LL3 L3 19 | # define LC3 0xffffffffffffffff 20 | # define LS3 0xffffffffffffffff 21 | # define LI3 0xffffffffffffffff 22 | # define XC LC0 23 | # define XS LS0 24 | # define XI LI0 25 | #else 26 | # define XC IC0 27 | # define XS IS0 28 | # define XI II0 29 | #endif 30 | #define I0 0x80000001 31 | #define II0 I0 32 | #define IC0 0xffffff81 33 | #define IS0 0xffff8001 34 | #define I1 0x80000000 35 | #define II1 I1 36 | #define IC1 0xffffff80 37 | #define IS1 0xffff8000 38 | #define I2 0x7fffffff 39 | #define II2 I2 40 | #define IC2 0x0000007f 41 | #define IS2 0x00007fff 42 | #define I3 0xffffffff 43 | #define II3 I3 44 | #define IC3 0xffffffff 45 | #define IS3 0xffffffff 46 | #define S0 0x8001 47 | #define S1 0x8000 48 | #define S2 0x7fff 49 | #define S3 0xffff 50 | #define C0 0x81 51 | #define C1 0x80 52 | #define C2 0x7f 53 | #define C3 0xff 54 | #define F0 0.25 55 | #define F1 0.75 56 | #define F2 -0.25 57 | #define F3 -0.75 58 | #define D0 0.25 59 | #define D1 0.75 60 | #define D2 -0.25 61 | #define D3 -0.75 62 | 63 | .data 512 64 | ok: 65 | .c "ok\n" 66 | .align 8 67 | t0: 68 | c0: 69 | .c 0 70 | uc0: 71 | .c 0 72 | s0: 73 | .s 0 74 | us0: 75 | .s 0 76 | .align 4 77 | i0: 78 | .i 0 79 | #if __WORDSIZE == 64 80 | ui0: 81 | .i 0 82 | .align 8 83 | l0: 84 | .l 0 85 | #endif 86 | f0: 87 | .f 0 88 | .align 8 89 | d0: 90 | .d 0 91 | 92 | . $($offc = c0 - t0) 93 | . $($offuc = uc0 - t0) 94 | . $($offs = s0 - t0) 95 | . $($offus = us0 - t0) 96 | . $($offi = i0 - t0) 97 | #if __WORDSIZE == 64 98 | . $($offui = ui0 - t0) 99 | . $($offl = l0 - t0) 100 | #endif 101 | . $($offf = f0 - t0) 102 | . $($offd = d0 - t0) 103 | -------------------------------------------------------------------------------- /lightning/check/ldsti.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstr-c.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstr.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstxi-c.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstxi.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstxr-c.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ldstxr.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/live.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/live.tst: -------------------------------------------------------------------------------- 1 | .data 16 2 | ok: 3 | .c "ok" 4 | 5 | .code 6 | jmpi main 7 | 8 | check_r0: 9 | prolog 10 | movi %v0 exit_r0 11 | movi %r0 1 12 | movi %r2 10 13 | // on x86 this changes %rax on other arches could use %r0 as temporary 14 | divi %r1 %r2 3 15 | live %r0 16 | // %r0 must still be 1 17 | jmpr %v0 18 | exit_r0: 19 | retr %r0 20 | epilog 21 | 22 | main: 23 | prolog 24 | calli check_r0 25 | retval %r1 26 | beqi r0_ok %r1 1 27 | calli @abort 28 | r0_ok: 29 | prepare 30 | pushargi ok 31 | finishi @puts 32 | ret 33 | epilog 34 | -------------------------------------------------------------------------------- /lightning/check/movzr.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/movzr.tst: -------------------------------------------------------------------------------- 1 | .data 8 2 | ok: 3 | .c "ok\n" 4 | 5 | #define CMOVR(N, T, OP, I0, I1, V, R0, R1, R2) \ 6 | movi %R1 I0 \ 7 | movi %R2 I1 \ 8 | movi %R0 V \ 9 | OP##r##T %R0 %R1 %R2 \ 10 | beqi OP##T##N##r_##R0##R1##R2 %R0 V \ 11 | calli @abort \ 12 | OP##T##N##r_##R0##R1##R2: 13 | 14 | /* reg0 = reg1 op reg0 */ 15 | #define CMOVR1(N, T, OP, I0, I1, V, R0, R1, R2) \ 16 | movi %R0 I1 \ 17 | movi %R1 I0 \ 18 | movi %R2 V \ 19 | OP##r##T %R0 %R1 %R0 \ 20 | beqr OP##T##N##r_1##R0##R1##R2 %R0 %R2 \ 21 | calli @abort \ 22 | OP##T##N##r_1##R0##R1##R2: 23 | 24 | #define TEST_CMOV1(N, OP, I0, I1, V, R0, R1, R2) \ 25 | CMOVR(N, , OP, I0, I1, V, R0, R1, R2) \ 26 | CMOVR1(N, , OP, I0, I1, V, R0, R1, R2) \ 27 | 28 | #define TEST_CMOV(N, OP, I0, I1, V) \ 29 | TEST_CMOV1(N, OP, I0, I1, V, v0, v1, v2) \ 30 | TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r0) \ 31 | TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r1) \ 32 | TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r2) \ 33 | TEST_CMOV1(N, OP, I0, I1, V, v1, v2, r1) \ 34 | TEST_CMOV1(N, OP, I0, I1, V, v1, v2, r2) \ 35 | TEST_CMOV1(N, OP, I0, I1, V, v2, r0, r1) \ 36 | TEST_CMOV1(N, OP, I0, I1, V, v2, r0, r2) \ 37 | TEST_CMOV1(N, OP, I0, I1, V, r0, r1, r2) 38 | 39 | #define MOVZR(N, I0, I1, V) TEST_CMOV(N, movz, I0, I1, V) 40 | #define MOVNR(N, I0, I1, V) TEST_CMOV(N, movn, I0, I1, V) 41 | 42 | .code 43 | prolog 44 | 45 | MOVZR(0, 0x0, 0x0, 0x0) 46 | MOVZR(1, 0xf7de, 0x0, 0xf7de) 47 | 48 | MOVZR(2, 0x0, 0xdead, 0xdead) 49 | MOVZR(3, 0xf7de, 0xdead, 0xdead) 50 | 51 | MOVNR(0, 0x0, 0x0, 0x0) 52 | MOVNR(1, 0xf7de, 0x0, 0x0) 53 | 54 | MOVNR(2, 0x0, 0xdead, 0x0) 55 | MOVNR(3, 0xf7de, 0xdead, 0xf7de) 56 | 57 | prepare 58 | pushargi ok 59 | ellipsis 60 | finishi @printf 61 | ret 62 | epilog 63 | -------------------------------------------------------------------------------- /lightning/check/nodata.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple test of using an alternate buffer for the code. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #if defined(__sgi) 10 | # include 11 | #endif 12 | 13 | #ifndef MAP_ANON 14 | # define MAP_ANON MAP_ANONYMOUS 15 | # ifndef MAP_ANONYMOUS 16 | # define MAP_ANONYMOUS 0 17 | # endif 18 | #endif 19 | 20 | #if !defined(__sgi) 21 | #define mmap_fd -1 22 | #endif 23 | 24 | jit_uint8_t *data; 25 | jit_state_t *_jit; 26 | jit_word_t data_length; 27 | jit_word_t note_length; 28 | #if defined(__sgi) 29 | int mmap_fd; 30 | #endif 31 | void (*function)(void); 32 | 33 | void 34 | gencode(jit_word_t flags) 35 | { 36 | jit_word_t offset; 37 | jit_word_t length; 38 | 39 | _jit = jit_new_state(); 40 | 41 | jit_name("main"); 42 | jit_prolog(); 43 | jit_prepare(); 44 | jit_pushargi((jit_word_t)"%f\n"); 45 | jit_ellipsis(); 46 | jit_pushargi_d(1.5); 47 | jit_finishi(printf); 48 | jit_note("nodata.c", __LINE__); 49 | 50 | /* call to jit_realize() is only required when using an alternate 51 | * code buffer. Note that not using mmap'ed memory may not work 52 | * on several ports and/or operating system versions */ 53 | jit_realize(); 54 | 55 | if (jit_get_data(&data_length, ¬e_length) != NULL) 56 | abort(); 57 | 58 | length = 0; 59 | if (!(flags & JIT_DISABLE_DATA)) 60 | length += data_length; 61 | if (!(flags & JIT_DISABLE_NOTE)) 62 | length += note_length; 63 | 64 | /* check that a too small buffer fails */ 65 | if (flags) 66 | jit_set_data(length ? data : NULL, length, flags); 67 | 68 | /* and calling again with enough space works */ 69 | offset = (length + 7) & -8; 70 | function = jit_emit(); 71 | if (function == NULL) 72 | abort(); 73 | 74 | jit_clear_state(); 75 | (*function)(); 76 | jit_destroy_state(); 77 | } 78 | 79 | int 80 | main(int argc, char *argv[]) 81 | { 82 | #if defined(__sgi) 83 | mmap_fd = open("/dev/zero", O_RDWR); 84 | #endif 85 | 86 | data = mmap(NULL, 4096, 87 | PROT_READ | PROT_WRITE, 88 | MAP_PRIVATE | MAP_ANON, mmap_fd, 0); 89 | assert(data != MAP_FAILED); 90 | #if defined(__sgi) 91 | close(mmap_fd); 92 | #endif 93 | 94 | init_jit(argv[0]); 95 | 96 | gencode(0); 97 | gencode(JIT_DISABLE_DATA); 98 | gencode(JIT_DISABLE_NOTE); 99 | gencode(JIT_DISABLE_DATA | JIT_DISABLE_NOTE); 100 | 101 | finish_jit(); 102 | 103 | munmap(data, 4096); 104 | 105 | return (0); 106 | } 107 | -------------------------------------------------------------------------------- /lightning/check/protect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple test of (un)protecting a code buffer. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define MARKER 10 10 | 11 | int 12 | main(int argc, char *argv[]) 13 | { 14 | jit_state_t *_jit; 15 | jit_node_t *load, *label, *ok; 16 | unsigned char *ptr; 17 | void (*function)(void); 18 | int mmap_prot, mmap_flags; 19 | 20 | init_jit(argv[0]); 21 | _jit = jit_new_state(); 22 | 23 | jit_prolog(); 24 | 25 | load = jit_movi(JIT_R0, 0); 26 | jit_ldr_c(JIT_R0, JIT_R0); 27 | ok = jit_forward(); 28 | jit_patch_at(jit_beqi(JIT_R0, MARKER), ok); 29 | jit_prepare(); 30 | jit_pushargi(1); 31 | jit_finishi(exit); 32 | label = jit_indirect(); 33 | jit_skip(1); /* Reserves enough space for a byte. */ 34 | jit_patch_at(load, label); 35 | jit_link(ok); 36 | jit_prepare(); 37 | jit_pushargi((jit_word_t)"%s\n"); 38 | jit_ellipsis(); 39 | jit_pushargi((jit_word_t)"ok"); 40 | jit_finishi(printf); 41 | 42 | function = jit_emit(); 43 | if (function == NULL) 44 | abort(); 45 | 46 | jit_unprotect (); 47 | ptr = jit_address (label); 48 | *ptr = MARKER; 49 | jit_protect (); 50 | 51 | jit_clear_state(); 52 | 53 | (*function)(); 54 | 55 | jit_destroy_state(); 56 | finish_jit(); 57 | 58 | return (0); 59 | } 60 | -------------------------------------------------------------------------------- /lightning/check/put.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/qalu_div.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/qalu_div.tst: -------------------------------------------------------------------------------- 1 | #include "qalu.inc" 2 | 3 | .code 4 | prolog 5 | #define QDIV(N, I0, I1, LO, HI) QALU(N, , qdiv, I0, I1, LO, HI) 6 | #define UQDIV(N, I0, I1, LO, HI) QALU(N, _u, qdiv, I0, I1, LO, HI) 7 | QDIV(0, 10, 3, 3, 1) 8 | QDIV(1, -33, 9, -3, -6) 9 | QDIV(2, -41, -7, 5, -6) 10 | QDIV(3, 65536, 4096, 16, 0) 11 | UQDIV(4, -1, -2, 1, 1) 12 | UQDIV(5, -2, -5, 1, 3) 13 | prepare 14 | pushargi ok 15 | ellipsis 16 | finishi @printf 17 | ret 18 | epilog 19 | -------------------------------------------------------------------------------- /lightning/check/qalu_mul.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/qalu_mul.tst: -------------------------------------------------------------------------------- 1 | #include "qalu.inc" 2 | 3 | .code 4 | prolog 5 | #define QMUL(N, I0, I1, LO, HI) QALU(N, , qmul, I0, I1, LO, HI) 6 | #define UQMUL(N, I0, I1, LO, HI) QALU(N, _u, qmul, I0, I1, LO, HI) 7 | QMUL(0, -2, -1, 2, 0) 8 | QMUL(1, 0, -1, 0, 0) 9 | QMUL(2, -1, 0, 0, 0) 10 | QMUL(3, 1, -1, -1, -1) 11 | #if __WORDSIZE == 32 12 | QMUL(4, 0x7ffff, 0x7ffff, 0xfff00001, 0x3f) 13 | UQMUL(5, 0xffffff, 0xffffff, 0xfe000001, 0xffff) 14 | QMUL(6, 0x80000000, -2, 0, 1) 15 | QMUL(7, 0x80000000, 2, 0, -1) 16 | QMUL(8, 0x80000001, 3, 0x80000003, -2) 17 | QMUL(9, 0x80000001, -3, 0x7ffffffd, 1) 18 | #else 19 | QMUL(4, 0x7ffffffff, 0x7ffffffff, 0xfffffff000000001, 0x3f) 20 | UQMUL(5, 0xffffffffff, 0xffffffffff, 0xfffffe0000000001, 0xffff) 21 | QMUL(6, 0x8000000000000000, -2, 0, 1) 22 | QMUL(7, 0x8000000000000000, 2, 0, -1) 23 | QMUL(8, 0x8000000000000001, 3, 0x8000000000000003, -2) 24 | QMUL(9, 0x8000000000000001, -3, 0x7ffffffffffffffd, 1) 25 | #endif 26 | prepare 27 | pushargi ok 28 | ellipsis 29 | finishi @printf 30 | ret 31 | epilog 32 | -------------------------------------------------------------------------------- /lightning/check/range.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ranger.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ret.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/ret.tst: -------------------------------------------------------------------------------- 1 | .data 16 2 | ok: 3 | .c "ok" 4 | 5 | .code 6 | jmpi main 7 | 8 | /* 9 | * very simple test on purpose because otherwise it would not trigger 10 | * the bug where the retr %r0 or retr_d %f0 would be omitted because 11 | * the argument was already the return register, but the register end 12 | * clobbered by another instruction, like the div*, and the wrong 13 | * value returned because the retr* was removed and this way, lost 14 | * information that the register was live at function exit. 15 | */ 16 | 17 | check_r0: 18 | prolog 19 | movi %r0 1 20 | movi %r2 10 21 | // on x86 this changes %rax on other arches could use %r0 as temporary 22 | divi %r1 %r2 3 23 | // %r0 must still be 1 24 | retr %r0 25 | epilog 26 | 27 | check_f0: 28 | prolog 29 | movi_d %f0 0.5 30 | movi_d %f2 10 31 | divi_d %f1 %f2 3 32 | retr_d %f0 33 | epilog 34 | 35 | main: 36 | prolog 37 | calli check_r0 38 | retval %r1 39 | beqi r0_ok %r1 1 40 | calli @abort 41 | r0_ok: 42 | calli check_f0 43 | retval_d %f1 44 | beqi_d f0_ok %f1 0.5 45 | calli @abort 46 | f0_ok: 47 | prepare 48 | pushargi ok 49 | finishi @puts 50 | ret 51 | epilog 52 | -------------------------------------------------------------------------------- /lightning/check/riprel.ok: -------------------------------------------------------------------------------- 1 | c s i l 2 | C S I 3 | 1.0 2.0 4 | -------------------------------------------------------------------------------- /lightning/check/rpn.ok: -------------------------------------------------------------------------------- 1 | 2 | C: 0 10 20 30 40 50 60 70 80 90 100 3 | F: 32 50 68 86 104 122 140 158 176 194 212 4 | 5 | F: 32 50 68 86 104 122 140 158 176 194 212 6 | C: 0 10 20 30 40 50 60 70 80 90 100 7 | -------------------------------------------------------------------------------- /lightning/check/run-test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ok=`echo $1 | sed -e 's@\.\(x87\|arm\|swf\)@@'` 4 | $1 | tr -d \\r > $1.log 5 | if cmp -s $srcdir/$ok.ok $1.log; then 6 | rm $1.log 7 | else 8 | diff $srcdir/$ok.ok $1.log 9 | exit 1 10 | fi 11 | -------------------------------------------------------------------------------- /lightning/check/setcode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple test of using an alternate buffer for the code. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #if defined(__sgi) 10 | # include 11 | #endif 12 | 13 | #ifndef MAP_ANON 14 | # define MAP_ANON MAP_ANONYMOUS 15 | # ifndef MAP_ANONYMOUS 16 | # define MAP_ANONYMOUS 0 17 | # endif 18 | #endif 19 | 20 | #if !defined(__sgi) 21 | #define mmap_fd -1 22 | #endif 23 | 24 | int 25 | main(int argc, char *argv[]) 26 | { 27 | jit_uint8_t *ptr; 28 | jit_state_t *_jit; 29 | jit_word_t length; 30 | #if defined(__sgi) 31 | int mmap_fd; 32 | #endif 33 | void (*function)(void); 34 | int mmap_prot, mmap_flags, result; 35 | 36 | #if defined(__sgi) 37 | mmap_fd = open("/dev/zero", O_RDWR); 38 | #endif 39 | 40 | mmap_prot = PROT_READ | PROT_WRITE; 41 | #if !(__OpenBSD__ || __APPLE__) 42 | mmap_prot |= PROT_EXEC; 43 | #endif 44 | #if __NetBSD__ 45 | mmap_prot = PROT_MPROTECT(mmap_prot); 46 | mmap_flags = 0; 47 | #else 48 | mmap_flags = MAP_PRIVATE; 49 | #endif 50 | mmap_flags |= MAP_ANON; 51 | ptr = mmap(NULL, 1024 * 1024, mmap_prot, mmap_flags, mmap_fd, 0); 52 | assert(ptr != MAP_FAILED); 53 | #if defined(__sgi) 54 | close(mmap_fd); 55 | #endif 56 | 57 | init_jit(argv[0]); 58 | _jit = jit_new_state(); 59 | 60 | jit_prolog(); 61 | jit_prepare(); 62 | jit_pushargi((jit_word_t)"%s\n"); 63 | jit_ellipsis(); 64 | jit_pushargi((jit_word_t)"ok"); 65 | jit_finishi(printf); 66 | 67 | /* call to jit_realize() is only required when using an alternate 68 | * code buffer. Note that not using mmap'ed memory may not work 69 | * on several ports and/or operating system versions */ 70 | jit_realize(); 71 | 72 | length = 0; 73 | if (jit_get_code(&length) != NULL) 74 | abort(); 75 | 76 | if (length <= 4) 77 | abort(); 78 | 79 | /* check that a too small buffer fails */ 80 | jit_set_code(ptr, 4); 81 | function = jit_emit(); 82 | if (function != NULL) 83 | abort(); 84 | 85 | #if __NetBSD__ 86 | result = mprotect(ptr, 1024 * 1024, PROT_READ | PROT_WRITE); 87 | assert(result == 0); 88 | #endif 89 | /* and calling again with enough space works */ 90 | jit_set_code(ptr, 1024 * 1024); 91 | function = jit_emit(); 92 | if (function == NULL) 93 | abort(); 94 | 95 | jit_clear_state(); 96 | #if __NetBSD__ || __OpenBSD__ || __APPLE__ 97 | result = mprotect(ptr, 1024 * 1024, PROT_READ | PROT_EXEC); 98 | assert(result == 0); 99 | #endif 100 | (*function)(); 101 | jit_destroy_state(); 102 | finish_jit(); 103 | 104 | munmap(ptr, 1024 * 1024); 105 | 106 | return (0); 107 | } 108 | -------------------------------------------------------------------------------- /lightning/check/skip.ok: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /lightning/check/skip.tst: -------------------------------------------------------------------------------- 1 | .data 32 2 | fmt: 3 | .c "%d\n" 4 | .code 5 | prolog 6 | skip 4 7 | prepare 8 | pushargi fmt 9 | ellipsis 10 | pushargi 10 11 | finishi @printf 12 | ret 13 | epilog 14 | -------------------------------------------------------------------------------- /lightning/check/stack.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/tramp.ok: -------------------------------------------------------------------------------- 1 | xfibs(32) = 7049155 2 | -------------------------------------------------------------------------------- /lightning/check/tramp.tst: -------------------------------------------------------------------------------- 1 | #if __WORDSIZE == 32 2 | # define SIZE 4 3 | #else 4 | # define SIZE 8 5 | #endif 6 | .data 8192 7 | fmt: 8 | .c "xfibs(%d) = %d\n" 9 | /* Simulate a language specific stack */ 10 | .align SIZE 11 | top: 12 | /* Top, or base of the stack */ 13 | .size SIZE 14 | stk: 15 | .size 8160 16 | 17 | .code 18 | jmpi main 19 | 20 | /* Usually a trampoline is created before the code that uses it, but 21 | * for testing purposes it is not required. 22 | * In this test case, it would mean "main" would be converted in a 23 | * different jit_state_t to native code, before xfibs was know. 24 | */ 25 | name xfibs 26 | xfibs: 27 | /* return address is in %r0 */ 28 | /* argument and return value in %v0 */ 29 | prolog 30 | tramp 64 31 | blti_u out %v0 2 32 | subi %v1 %v0 1 /* V1 = N-1 */ 33 | subi %v2 %v0 2 /* V1 = N-2 */ 34 | 35 | /* save return address */ 36 | ldi %r1 top 37 | stxi $(SIZE * 0) %r1 %r0 38 | /* save operands */ 39 | stxi $(SIZE * 1) %r1 %v0 40 | stxi $(SIZE * 2) %r1 %v1 41 | stxi $(SIZE * 3) %r1 %v2 42 | /* adjust "language" stack */ 43 | addi %r1 %r1 $(SIZE * 4) 44 | sti top %r1 45 | 46 | /* return address */ 47 | movi %r0 ret1 48 | /* argument */ 49 | movr %v0 %v1 50 | /* indirect goto */ 51 | jmpi xfibs 52 | ret1: 53 | movr %v1 %v0 /* V1 = rfibs(N-1) */ 54 | /* save V1 */ 55 | ldi %r1 top 56 | stxi $(-SIZE * 2) %r1 %v1 57 | 58 | /* reload V2 */ 59 | ldxi %v2 %r1 $(-SIZE * 1) 60 | 61 | /* return address */ 62 | movi %r0 ret2 63 | /* argument */ 64 | movr %v0 %v2 65 | /* indirect goto */ 66 | jmpi xfibs 67 | ret2: 68 | movr %v2 %v0 /* V2 = rfibs(N-2) */ 69 | 70 | /* reload return address */ 71 | ldi %r1 top 72 | subi %r1 %r1 $(SIZE * 4) 73 | ldxi %r0 %r1 $(SIZE * 0) 74 | /* reload operands */ 75 | ldxi %v0 %r1 $(SIZE * 1) 76 | ldxi %v1 %r1 $(SIZE * 2) 77 | /* V2 already loaded */ 78 | /* update "language" stack */ 79 | sti top %r1 80 | 81 | addi %v1 %v1 1 82 | addr %v0 %v1 %v2 83 | jmpr %r0 84 | out: 85 | movi %v0 1 86 | jmpr %r0 87 | epilog 88 | 89 | name main 90 | main: 91 | prolog 92 | frame 64 93 | 94 | /* Initialize language stack */ 95 | movi %r0 stk 96 | sti top %r0 97 | 98 | /* return address */ 99 | movi %r0 done 100 | /* argument */ 101 | movi %v0 32 102 | jmpi xfibs 103 | done: 104 | prepare 105 | pushargi fmt 106 | ellipsis 107 | pushargi 32 108 | pushargr %v0 109 | finishi @printf 110 | ret 111 | epilog 112 | -------------------------------------------------------------------------------- /lightning/check/va_list.ok: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /lightning/check/varargs.ok: -------------------------------------------------------------------------------- 1 | 0 1 2 3 4 5 6 7 8 9 2 | 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 3 | 0 0.0 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 6 6.0 7 7.0 8 8.0 9 9.0 4 | 0.0 0 1.0 1 2.0 2 3.0 3 4.0 4 5.0 5 6.0 6 7.0 7 8.0 8 9.0 9 5 | -------------------------------------------------------------------------------- /lightning/doc/.cvsignore: -------------------------------------------------------------------------------- 1 | *.info* 2 | stamp-* 3 | version.texi 4 | -------------------------------------------------------------------------------- /lightning/doc/.gitignore: -------------------------------------------------------------------------------- 1 | *.info* 2 | stamp-* 3 | /version.texi 4 | 5 | texinfo.tex 6 | mdate-sh 7 | 8 | fact 9 | ifib 10 | incr 11 | printf 12 | rfib 13 | rpn 14 | -------------------------------------------------------------------------------- /lightning/doc/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2023 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU lightning. 5 | # 6 | # GNU lightning is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as published 8 | # by the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU lightning is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | # License for more details. 15 | # 16 | 17 | AM_CFLAGS = -I $(top_builddir)/include -I$(top_srcdir)/include \ 18 | -D_GNU_SOURCE $(LIGHTNING_CFLAGS) 19 | 20 | info_TEXINFOS = lightning.texi 21 | MOSTLYCLEANFILES = lightning.tmp 22 | 23 | lightning_TEXINFOS = body.texi version.texi 24 | 25 | noinst_PROGRAMS = incr printf rpn rfib ifib fact 26 | 27 | $(top_builddir)/lib/liblightning.la: 28 | cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la 29 | 30 | incr_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 31 | incr_SOURCES = incr.c 32 | 33 | printf_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 34 | printf_SOURCES = printf.c 35 | 36 | rpn_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 37 | rpn_SOURCES = rpn.c 38 | 39 | rfib_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 40 | rfib_SOURCES = rfib.c 41 | 42 | ifib_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 43 | ifib_SOURCES = ifib.c 44 | 45 | fact_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB) 46 | fact_SOURCES = fact.c 47 | -------------------------------------------------------------------------------- /lightning/doc/fact.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jit_state_t *_jit; 5 | 6 | typedef long (*pwfw_t)(long); /* Pointer to Long Function of Long */ 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | pwfw_t factorial; 11 | long arg; 12 | jit_node_t *ac; /* Accumulator */ 13 | jit_node_t *in; /* Argument */ 14 | jit_node_t *call; 15 | jit_node_t *fact; 16 | jit_node_t *jump; 17 | jit_node_t *fact_entry; 18 | jit_node_t *fact_out; 19 | 20 | init_jit(argv[0]); 21 | _jit = jit_new_state(); 22 | 23 | /* declare a forward label */ 24 | fact = jit_forward(); 25 | 26 | jit_prolog(); /* Entry point of the factorial function */ 27 | in = jit_arg(); /* Receive an integer argument */ 28 | jit_getarg(JIT_R0, in); /* Move argument to RO */ 29 | jit_prepare(); 30 | jit_pushargi(1); /* This is the accumulator */ 31 | jit_pushargr(JIT_R0); /* This is the argument */ 32 | call = jit_finishi(NULL); /* Call the tail call optimized function */ 33 | jit_patch_at(call, fact); /* Patch call to forward defined function */ 34 | /* the above could have been written as: 35 | * jit_patch_at(jit_finishi(NULL), fact); 36 | */ 37 | jit_retval(JIT_R0); /* Fetch the result */ 38 | jit_retr(JIT_R0); /* Return it */ 39 | jit_epilog(); /* Epilog *before* label before prolog */ 40 | 41 | /* define the forward label */ 42 | jit_link(fact); /* Entry point of the helper function */ 43 | jit_prolog(); 44 | jit_frame(16); /* Reserve 16 bytes in the stack */ 45 | fact_entry = jit_label(); /* This is the tail call entry point */ 46 | ac = jit_arg(); /* The accumulator is the first argument */ 47 | in = jit_arg(); /* The factorial argument */ 48 | jit_getarg(JIT_R0, ac); /* Move the accumulator to R0 */ 49 | jit_getarg(JIT_R1, in); /* Move the argument to R1 */ 50 | fact_out = jit_blei(JIT_R1, 1); /* Done if argument is one or less */ 51 | jit_mulr(JIT_R0, JIT_R0, JIT_R1); /* accumulator *= argument */ 52 | jit_putargr(JIT_R0, ac); /* Update the accumulator */ 53 | jit_subi(JIT_R1, JIT_R1, 1); /* argument -= 1 */ 54 | jit_putargr(JIT_R1, in); /* Update the argument */ 55 | jump = jit_jmpi(); 56 | jit_patch_at(jump, fact_entry); /* Tail Call Optimize it! */ 57 | jit_patch(fact_out); 58 | jit_retr(JIT_R0); /* Return the accumulator */ 59 | 60 | factorial = jit_emit(); 61 | /* no need to query information about resolved addresses */ 62 | jit_clear_state(); 63 | 64 | if (argc == 2) 65 | arg = atoi(argv[1]); 66 | else 67 | arg = 5; 68 | 69 | /* call the generated code */ 70 | printf("factorial(%ld) = %ld\n", arg, factorial(arg)); 71 | /* release all memory associated with the _jit identifier */ 72 | jit_destroy_state(); 73 | finish_jit(); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /lightning/doc/ifib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jit_state_t *_jit; 5 | 6 | typedef int (*pifi)(int); /* Pointer to Int Function of Int */ 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | pifi fib; 11 | jit_node_t *in; /* offset of the argument */ 12 | jit_node_t *ref; /* to patch the forward reference */ 13 | jit_node_t *zero; /* to patch the forward reference */ 14 | jit_node_t *jump; /* jump to start of loop */ 15 | jit_node_t *loop; /* start of the loop */ 16 | 17 | init_jit(argv[0]); 18 | _jit = jit_new_state(); 19 | 20 | jit_prolog (); 21 | in = jit_arg (); 22 | jit_getarg (JIT_R0, in); /* R0 = n */ 23 | zero = jit_beqi (JIT_R0, 0); 24 | jit_movr (JIT_R1, JIT_R0); 25 | jit_movi (JIT_R0, 1); 26 | ref = jit_blei (JIT_R1, 2); 27 | jit_subi (JIT_R2, JIT_R1, 2); 28 | jit_movr (JIT_R1, JIT_R0); 29 | 30 | loop= jit_label(); 31 | jit_subi (JIT_R2, JIT_R2, 1); /* decr. counter */ 32 | jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */ 33 | jit_addr (JIT_R0, JIT_R0, JIT_R1); /* R0 = R0 + R1 */ 34 | jit_movr (JIT_R1, JIT_V0); /* R1 = V0 */ 35 | jump= jit_bnei (JIT_R2, 0); /* if (R2) goto loop; */ 36 | jit_patch_at(jump, loop); 37 | 38 | jit_patch(ref); /* patch forward jump */ 39 | jit_patch(zero); /* patch forward jump */ 40 | jit_retr (JIT_R0); 41 | 42 | /* call the generated code, passing 36 as an argument */ 43 | fib = jit_emit(); 44 | jit_clear_state(); 45 | printf("fib(%d) = %d\n", 36, fib(36)); 46 | jit_destroy_state(); 47 | finish_jit(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /lightning/doc/incr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jit_state_t *_jit; 5 | 6 | typedef int (*pifi)(int); /* Pointer to Int Function of Int */ 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | jit_node_t *in; 11 | pifi incr; 12 | 13 | init_jit(argv[0]); 14 | _jit = jit_new_state(); 15 | 16 | jit_prolog(); /* @t{ prolog } */ 17 | in = jit_arg(); /* @t{ in = arg } */ 18 | jit_getarg(JIT_R0, in); /* @t{ getarg R0 } */ 19 | jit_addi(JIT_R0, JIT_R0, 1); /* @t{ addi R0\, R0\, 1 } */ 20 | jit_retr(JIT_R0); /* @t{ retr R0 } */ 21 | 22 | incr = jit_emit(); 23 | jit_clear_state(); 24 | 25 | /* call the generated code\, passing 5 as an argument */ 26 | printf("%d + 1 = %d\n", 5, incr(5)); 27 | 28 | jit_destroy_state(); 29 | finish_jit(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lightning/doc/lightning.texi: -------------------------------------------------------------------------------- 1 | \input texinfo.tex @c -*- texinfo -*- 2 | @c %**start of header (This is for running Texinfo on a region.) 3 | 4 | @setfilename lightning.info 5 | 6 | @set TITLE Using @sc{gnu} @i{lightning} 7 | @set TOPIC installing and using 8 | 9 | @settitle @value{TITLE} 10 | 11 | @c --------------------------------------------------------------------- 12 | @c Common macros 13 | @c --------------------------------------------------------------------- 14 | 15 | @macro bulletize{a} 16 | @item 17 | \a\ 18 | @end macro 19 | 20 | @macro rem{a} 21 | @r{@i{\a\}} 22 | @end macro 23 | 24 | @macro gnu{} 25 | @sc{gnu} 26 | @end macro 27 | 28 | @macro lightning{} 29 | @gnu{} @i{lightning} 30 | @end macro 31 | 32 | @c --------------------------------------------------------------------- 33 | @c Macros for Texinfo 3.1/4.0 compatibility 34 | @c --------------------------------------------------------------------- 35 | 36 | @c @hlink (macro), @url and @email are used instead of @uref for Texinfo 3.1 37 | @c compatibility 38 | @macro hlink{url, link} 39 | \link\ (\url\) 40 | @end macro 41 | 42 | @c ifhtml can only be true in Texinfo 4.0, which has uref 43 | @ifhtml 44 | @unmacro hlink 45 | 46 | @macro hlink{url, link} 47 | @uref{\url\, \link\} 48 | @end macro 49 | 50 | @macro email{mail} 51 | @uref{mailto:\mail\, , \mail\} 52 | @end macro 53 | 54 | @macro url{url} 55 | @uref{\url\} 56 | @end macro 57 | @end ifhtml 58 | 59 | @c --------------------------------------------------------------------- 60 | @c References to the other half of the manual 61 | @c --------------------------------------------------------------------- 62 | 63 | @macro usingref{node, name} 64 | @ref{\node\, , \name\} 65 | @end macro 66 | 67 | @c --------------------------------------------------------------------- 68 | @c End of macro section 69 | @c --------------------------------------------------------------------- 70 | 71 | @include version.texi 72 | @include body.texi 73 | 74 | @c %**end of header (This is for running Texinfo on a region.) 75 | 76 | @c *********************************************************************** 77 | 78 | @bye 79 | -------------------------------------------------------------------------------- /lightning/doc/printf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jit_state_t *_jit; 5 | 6 | typedef void (*pvfi)(int); /* Pointer to Void Function of Int */ 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | pvfi myFunction; /* ptr to generated code */ 11 | jit_node_t *start, *end; /* a couple of labels */ 12 | jit_node_t *in; /* to get the argument */ 13 | 14 | init_jit(argv[0]); 15 | _jit = jit_new_state(); 16 | 17 | start = jit_note(__FILE__, __LINE__); 18 | jit_prolog(); 19 | in = jit_arg(); 20 | jit_getarg(JIT_R1, in); 21 | jit_prepare(); 22 | jit_pushargi((jit_word_t)"generated %d bytes\n"); 23 | jit_ellipsis(); 24 | jit_pushargr(JIT_R1); 25 | jit_finishi(printf); 26 | jit_ret(); 27 | jit_epilog(); 28 | end = jit_note(__FILE__, __LINE__); 29 | 30 | myFunction = jit_emit(); 31 | 32 | /* call the generated code, passing its size as argument */ 33 | myFunction((char*)jit_address(end) - (char*)jit_address(start)); 34 | jit_clear_state(); 35 | 36 | jit_disassemble(); 37 | 38 | jit_destroy_state(); 39 | finish_jit(); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /lightning/doc/rfib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static jit_state_t *_jit; 5 | 6 | typedef int (*pifi)(int); /* Pointer to Int Function of Int */ 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | pifi fib; 11 | jit_node_t *label; 12 | jit_node_t *call; 13 | jit_node_t *in; /* offset of the argument */ 14 | jit_node_t *ref; /* to patch the forward reference */ 15 | jit_node_t *zero; /* to patch the forward reference */ 16 | 17 | init_jit(argv[0]); 18 | _jit = jit_new_state(); 19 | 20 | label = jit_label(); 21 | jit_prolog (); 22 | in = jit_arg (); 23 | jit_getarg (JIT_R0, in); /* R0 = n */ 24 | zero = jit_beqi (JIT_R0, 0); 25 | jit_movr (JIT_V0, JIT_R0); /* V0 = R0 */ 26 | jit_movi (JIT_R0, 1); 27 | ref = jit_blei (JIT_V0, 2); 28 | jit_subi (JIT_V1, JIT_V0, 1); /* V1 = n-1 */ 29 | jit_subi (JIT_V2, JIT_V0, 2); /* V2 = n-2 */ 30 | jit_prepare(); 31 | jit_pushargr(JIT_V1); 32 | call = jit_finishi(NULL); 33 | jit_patch_at(call, label); 34 | jit_retval(JIT_V1); /* V1 = fib(n-1) */ 35 | jit_prepare(); 36 | jit_pushargr(JIT_V2); 37 | call = jit_finishi(NULL); 38 | jit_patch_at(call, label); 39 | jit_retval(JIT_R0); /* R0 = fib(n-2) */ 40 | jit_addr(JIT_R0, JIT_R0, JIT_V1); /* R0 = R0 + V1 */ 41 | 42 | jit_patch(ref); /* patch jump */ 43 | jit_patch(zero); /* patch jump */ 44 | jit_retr(JIT_R0); 45 | 46 | /* call the generated code, passing 32 as an argument */ 47 | fib = jit_emit(); 48 | jit_clear_state(); 49 | printf("fib(%d) = %d\n", 32, fib(32)); 50 | jit_destroy_state(); 51 | finish_jit(); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /lightning/doc/rpn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef int (*pifi)(int); /* Pointer to Int Function of Int */ 5 | 6 | static jit_state_t *_jit; 7 | 8 | void stack_push(int reg, int *sp) 9 | { 10 | jit_stxi_i (*sp, JIT_FP, reg); 11 | *sp += sizeof (int); 12 | } 13 | 14 | void stack_pop(int reg, int *sp) 15 | { 16 | *sp -= sizeof (int); 17 | jit_ldxi_i (reg, JIT_FP, *sp); 18 | } 19 | 20 | jit_node_t *compile_rpn(char *expr) 21 | { 22 | jit_node_t *in, *fn; 23 | int stack_base, stack_ptr; 24 | 25 | fn = jit_note(NULL, 0); 26 | jit_prolog(); 27 | in = jit_arg_i(); 28 | stack_ptr = stack_base = jit_allocai (32 * sizeof (int)); 29 | 30 | jit_getarg_i(JIT_R2, in); 31 | 32 | while (*expr) { 33 | char buf[32]; 34 | int n; 35 | if (sscanf(expr, "%[0-9]%n", buf, &n)) { 36 | expr += n - 1; 37 | stack_push(JIT_R0, &stack_ptr); 38 | jit_movi(JIT_R0, atoi(buf)); 39 | } else if (*expr == 'x') { 40 | stack_push(JIT_R0, &stack_ptr); 41 | jit_movr(JIT_R0, JIT_R2); 42 | } else if (*expr == '+') { 43 | stack_pop(JIT_R1, &stack_ptr); 44 | jit_addr(JIT_R0, JIT_R1, JIT_R0); 45 | } else if (*expr == '-') { 46 | stack_pop(JIT_R1, &stack_ptr); 47 | jit_subr(JIT_R0, JIT_R1, JIT_R0); 48 | } else if (*expr == '*') { 49 | stack_pop(JIT_R1, &stack_ptr); 50 | jit_mulr(JIT_R0, JIT_R1, JIT_R0); 51 | } else if (*expr == '/') { 52 | stack_pop(JIT_R1, &stack_ptr); 53 | jit_divr(JIT_R0, JIT_R1, JIT_R0); 54 | } else { 55 | fprintf(stderr, "cannot compile: %s\n", expr); 56 | abort(); 57 | } 58 | ++expr; 59 | } 60 | jit_retr(JIT_R0); 61 | jit_epilog(); 62 | return fn; 63 | } 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | jit_node_t *nc, *nf; 68 | pifi c2f, f2c; 69 | int i; 70 | 71 | init_jit(argv[0]); 72 | _jit = jit_new_state(); 73 | 74 | nc = compile_rpn("32x9*5/+"); 75 | nf = compile_rpn("x32-5*9/"); 76 | (void)jit_emit(); 77 | c2f = (pifi)jit_address(nc); 78 | f2c = (pifi)jit_address(nf); 79 | jit_clear_state(); 80 | 81 | printf("\nC:"); 82 | for (i = 0; i <= 100; i += 10) printf("%3d ", i); 83 | printf("\nF:"); 84 | for (i = 0; i <= 100; i += 10) printf("%3d ", c2f(i)); 85 | printf("\n"); 86 | 87 | printf("\nF:"); 88 | for (i = 32; i <= 212; i += 18) printf("%3d ", i); 89 | printf("\nC:"); 90 | for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i)); 91 | printf("\n"); 92 | 93 | jit_destroy_state(); 94 | finish_jit(); 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /lightning/gnulib-lib/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.am 2 | /dummy.c 3 | -------------------------------------------------------------------------------- /lightning/include/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2000, 2001, 2002, 2012-2023 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU lightning. 5 | # 6 | # GNU lightning is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as published 8 | # by the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU lightning is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | # License for more details. 15 | # 16 | 17 | SUBDIRS = \ 18 | lightning 19 | 20 | nodist_include_HEADERS = lightning.h 21 | -------------------------------------------------------------------------------- /lightning/include/lightning/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2000, 2001, 2002, 2012-2022 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU lightning. 5 | # 6 | # GNU lightning is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as published 8 | # by the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU lightning is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | # License for more details. 15 | # 16 | 17 | lightning_includedir = $(includedir)/lightning 18 | 19 | EXTRA_DIST = \ 20 | jit_private.h 21 | 22 | if cpu_arm 23 | lightning_include_HEADERS = \ 24 | jit_arm.h 25 | endif 26 | if cpu_mips 27 | lightning_include_HEADERS = \ 28 | jit_mips.h 29 | endif 30 | if cpu_ppc 31 | lightning_include_HEADERS = \ 32 | jit_ppc.h 33 | endif 34 | if cpu_sparc 35 | lightning_include_HEADERS = \ 36 | jit_sparc.h 37 | endif 38 | if cpu_x86 39 | lightning_include_HEADERS = \ 40 | jit_x86.h 41 | endif 42 | if cpu_ia64 43 | lightning_include_HEADERS = \ 44 | jit_ia64.h 45 | endif 46 | if cpu_hppa 47 | lightning_include_HEADERS = \ 48 | jit_hppa.h 49 | endif 50 | if cpu_aarch64 51 | lightning_include_HEADERS = \ 52 | jit_aarch64.h 53 | endif 54 | if cpu_s390 55 | lightning_include_HEADERS = \ 56 | jit_s390.h 57 | endif 58 | if cpu_alpha 59 | lightning_include_HEADERS = \ 60 | jit_alpha.h 61 | endif 62 | if cpu_riscv 63 | lightning_include_HEADERS = \ 64 | jit_riscv.h 65 | endif 66 | if cpu_loongarch 67 | lightning_include_HEADERS = \ 68 | jit_loongarch.h 69 | endif 70 | -------------------------------------------------------------------------------- /lightning/include/lightning/jit_aarch64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU lightning. 5 | * 6 | * GNU lightning is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU Lesser General Public License as published 8 | * by the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU lightning is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * Authors: 17 | * Paulo Cesar Pereira de Andrade 18 | */ 19 | 20 | #ifndef _jit_aarch64_h 21 | #define _jit_aarch64_h 22 | 23 | #define JIT_HASH_CONSTS 0 24 | #define JIT_NUM_OPERANDS 3 25 | 26 | #if __APPLE__ 27 | # define PACKED_STACK 1 28 | #endif 29 | 30 | /* 31 | * Types 32 | */ 33 | #define JIT_FP _R29 34 | typedef enum { 35 | #define jit_r(i) (_R9 + (i)) 36 | #define jit_r_num() 7 37 | #define jit_v(i) (_R19 + (i)) 38 | #define jit_v_num() 10 39 | #define jit_f(i) (_V8 + (i)) 40 | #define jit_f_num() 8 41 | #define JIT_R0 _R9 42 | #define JIT_R1 _R10 43 | #define JIT_R2 _R11 44 | #define JIT_R3 _R12 45 | #define JIT_R4 _R13 46 | #define JIT_R5 _R14 47 | #define JIT_R6 _R15 48 | _R8, /* indirect result */ 49 | _R18, /* platform register */ 50 | _R17, /* IP1 */ 51 | _R16, /* IP0 */ 52 | _R9, _R10, _R11, _R12, /* temporaries */ 53 | _R13, _R14, _R15, 54 | #define JIT_V0 _R19 55 | #define JIT_V1 _R20 56 | #define JIT_V2 _R21 57 | #define JIT_V3 _R22 58 | #define JIT_V4 _R23 59 | #define JIT_V5 _R24 60 | #define JIT_V6 _R25 61 | #define JIT_V7 _R26 62 | #define JIT_V8 _R27 63 | #define JIT_V9 _R28 64 | _R19, _R20, _R21, _R22, /* callee save */ 65 | _R23, _R24, _R25, _R26, 66 | _R27, _R28, 67 | _SP, /* stack pointer */ 68 | _R30, /* link register */ 69 | _R29, /* frame pointer */ 70 | _R7, _R6, _R5, _R4, 71 | _R3, _R2, _R1, _R0, 72 | #define JIT_F0 _V8 73 | #define JIT_F1 _V9 74 | #define JIT_F2 _V10 75 | #define JIT_F3 _V11 76 | #define JIT_F4 _V12 77 | #define JIT_F5 _V13 78 | #define JIT_F6 _V14 79 | #define JIT_F7 _V15 80 | _V31, _V30, _V29, _V28, /* temporaries */ 81 | _V27, _V26, _V25, _V24, 82 | _V23, _V22, _V21, _V20, 83 | _V19, _V18, _V17, _V16, 84 | /* callee save */ 85 | _V8, _V9, _V10, _V11, 86 | _V12, _V13, _V14, _V15, 87 | _V7, _V6, _V5, _V4, /* arguments */ 88 | _V3, _V2, _V1, _V0, 89 | _NOREG, 90 | #define JIT_NOREG _NOREG 91 | } jit_reg_t; 92 | 93 | #endif /* _jit_aarch64_h */ 94 | -------------------------------------------------------------------------------- /lightning/include/lightning/jit_loongarch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU lightning. 5 | * 6 | * GNU lightning is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU Lesser General Public License as published 8 | * by the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU lightning is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * Authors: 17 | * Paulo Cesar Pereira de Andrade 18 | */ 19 | 20 | #ifndef _jit_loongarch_h 21 | #define _jit_loongarch_h 22 | 23 | /* 24 | * Types 25 | */ 26 | #define JIT_FP _FP 27 | typedef enum { 28 | #define jit_r_num() 9 29 | #define jit_r(i) (_T0 - (i)) 30 | #define JIT_R0 _T0 31 | #define JIT_R1 _T1 32 | #define JIT_R2 _T2 33 | #define JIT_R3 _T3 34 | #define JIT_R4 _T4 35 | #define JIT_R5 _T5 36 | #define JIT_R6 _T6 37 | #define JIT_R7 _T7 38 | #define JIT_R8 _T8 39 | _T8, _T7, _T6, _T5, _T4, _T3, _T2, _T1, _T0, 40 | #define jit_v_num() 9 41 | #define jit_v(i) (_S0 - (i)) 42 | #define JIT_V0 _S0 43 | #define JIT_V1 _S1 44 | #define JIT_V2 _S2 45 | #define JIT_V3 _S3 46 | #define JIT_V4 _S4 47 | #define JIT_V5 _S5 48 | #define JIT_V6 _S6 49 | #define JIT_V7 _S7 50 | #define JIT_V8 _S8 51 | _S8, _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0, 52 | _A7, _A6, _A5, _A4, _A3, _A2, _A1, _A0, 53 | _FP, 54 | _R21, 55 | _ZERO, 56 | _RA, 57 | _TP, 58 | _SP, 59 | _FT0, _FT1, _FT2, _FT3, _FT4, _FT5, _FT6, _FT7, 60 | _FT8, _FT9, _FT10, _FT11, _FT12, _FT13, _FT14, _FT15, 61 | _FA7, _FA6, _FA5, _FA4, FA3, _FA2, _FA1, _FA0, 62 | #define jit_f_num() 8 63 | #define jit_f(i) (_FS0 - (i)) 64 | #define JIT_F0 _FS0 65 | #define JIT_F1 _FS1 66 | #define JIT_F2 _FS2 67 | #define JIT_F3 _FS3 68 | #define JIT_F4 _FS4 69 | #define JIT_F5 _FS5 70 | #define JIT_F6 _FS6 71 | #define JIT_F7 _FS7 72 | _FS7, _FS6, _FS5, _FS4, _FS3, _FS2, _FS1, _FS0, 73 | #define JIT_NOREG _NOREG 74 | _NOREG, 75 | } jit_reg_t; 76 | 77 | #endif /* _jit_loongarch_h */ 78 | -------------------------------------------------------------------------------- /lightning/include/lightning/jit_ppc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU lightning. 5 | * 6 | * GNU lightning is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU Lesser General Public License as published 8 | * by the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU lightning is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * Authors: 17 | * Paulo Cesar Pereira de Andrade 18 | */ 19 | 20 | #ifndef _jit_ppc_h 21 | #define _jit_ppc_h 22 | 23 | #define JIT_HASH_CONSTS 1 24 | #define JIT_NUM_OPERANDS 3 25 | #if defined(_AIX) && !defined(_CALL_AIX) && !defined(_CALL_LINUX) 26 | # define _CALL_AIXDESC 1 27 | #endif 28 | 29 | /* 30 | * Types 31 | */ 32 | typedef enum { 33 | #define jit_r(i) (_R28 + (i)) 34 | #define jit_r_num() 3 35 | #define jit_v(i) (_R27 - (i)) 36 | #define jit_v_num() 14 37 | #define jit_f(i) (_F14 + (i)) 38 | #define jit_f_num() 8 39 | _R0, 40 | #define JIT_R0 _R28 41 | #define JIT_R1 _R29 42 | #define JIT_R2 _R30 43 | _R11, _R12, _R13, _R2, 44 | #define JIT_V0 jit_v(0) 45 | #define JIT_V1 jit_v(1) 46 | #define JIT_V2 jit_v(2) 47 | #define JIT_V3 jit_v(3) 48 | #define JIT_V4 jit_v(4) 49 | #define JIT_V5 jit_v(5) 50 | #define JIT_V6 jit_v(6) 51 | #define JIT_V7 jit_v(7) 52 | #define JIT_V8 jit_v(8) 53 | #define JIT_V9 jit_v(9) 54 | #define JIT_V10 jit_v(10) 55 | #define JIT_V11 jit_v(11) 56 | #define JIT_V12 jit_v(12) 57 | #define JIT_V13 jit_v(13) 58 | _R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, 59 | _R22, _R23, _R24, _R25, _R26, _R27, _R28, _R29, 60 | _R30, 61 | _R1, 62 | #define JIT_FP _R31 63 | _R31, 64 | _R10, _R9, _R8, _R7, _R6, _R5, _R4, _R3, 65 | _F0, 66 | _F14, _F15, _F16, _F17, _F18, _F19, _F20, _F21, 67 | #define JIT_F0 _F14 68 | #define JIT_F1 _F15 69 | #define JIT_F2 _F16 70 | #define JIT_F3 _F17 71 | #define JIT_F4 _F18 72 | #define JIT_F5 _F19 73 | #define JIT_F6 _F20 74 | #define JIT_F7 _F21 75 | /* FIXME _F20-_F31 not (easily) accessible and only _F14-_F21 76 | * saved/restored (if used) */ 77 | _F22, _F23, _F24, _F25, _F26, _F27, _F28, _F29, 78 | _F30, _F31, 79 | _F13, _F12, _F11, _F10, _F9, _F8, _F7, _F6, 80 | _F5, _F4, _F3, _F2, _F1, 81 | _NOREG, 82 | #define JIT_NOREG _NOREG 83 | } jit_reg_t; 84 | 85 | #endif /* _jit_ppc_h */ 86 | -------------------------------------------------------------------------------- /lightning/include/lightning/jit_s390.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU lightning. 5 | * 6 | * GNU lightning is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU Lesser General Public License as published 8 | * by the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU lightning is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | * License for more details. 15 | * 16 | * Authors: 17 | * Paulo Cesar Pereira de Andrade 18 | */ 19 | 20 | #ifndef _jit_s390_h 21 | #define _jit_s390_h 22 | 23 | #define JIT_HASH_CONSTS 1 24 | #define JIT_NUM_OPERANDS 2 25 | 26 | /* 27 | * Types 28 | */ 29 | #define JIT_FP _R13 30 | typedef enum { 31 | #define jit_r(i) (_R12 + ((i) << 1)) 32 | #define jit_r_num() 3 33 | #define jit_v(i) (_R11 + ((i) << 1)) 34 | #define jit_v_num() 3 35 | #define jit_f(i) (_F8 + (i)) 36 | #define jit_f_num() 6 37 | #define JIT_R0 _R12 38 | #define JIT_R1 _R10 39 | #define JIT_R2 _R8 40 | #define JIT_V0 _R11 41 | #define JIT_V1 _R9 42 | #define JIT_V2 _R7 43 | _R0, _R1, /* Volatile */ 44 | _R12, /* Saved, GOT */ 45 | _R11, _R10, _R9, _R8, /* Saved */ 46 | _R7, /* Saved */ 47 | _R6, /* Saved, parameter */ 48 | _R5, _R4, _R3, /* Parameter passing */ 49 | _R2, /* Volatile, parameter and return value */ 50 | _R13, /* Saved, literal pool pointer */ 51 | _R14, /* Volatile, return address */ 52 | _R15, /* Saved, stack pointer */ 53 | #define JIT_F0 _F8 54 | #define JIT_F1 _F9 55 | #define JIT_F2 _F10 56 | #define JIT_F3 _F11 57 | #define JIT_F4 _F12 58 | #define JIT_F5 _F13 59 | _F1, _F3, _F5, _F7, /* Volatile */ 60 | _F14, _F15, _F8, _F9, /* Saved */ 61 | _F10, _F11, _F12, _F13, /* Saved */ 62 | _F6, _F4, _F2, /* Volatile, parameter */ 63 | _F0, /* Volatile, parameter and return value */ 64 | _NOREG, 65 | #define JIT_NOREG _NOREG 66 | } jit_reg_t; 67 | 68 | typedef struct { 69 | jit_uint32_t flogr : 1; 70 | } jit_cpu_t; 71 | 72 | /* 73 | * Initialization 74 | */ 75 | extern jit_cpu_t jit_cpu; 76 | 77 | #endif /* _jit_s390_h */ 78 | -------------------------------------------------------------------------------- /lightning/lib/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2000, 2001, 2002, 2012-2022 Free Software Foundation, Inc. 3 | # 4 | # This file is part of GNU lightning. 5 | # 6 | # GNU lightning is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Lesser General Public License as published 8 | # by the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU lightning is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 | # License for more details. 15 | # 16 | 17 | AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ 18 | -D_GNU_SOURCE $(LIGHTNING_CFLAGS) 19 | liblightning_LTLIBRARIES = liblightning.la 20 | liblightning_la_LDFLAGS = -version-info 2:0:0 21 | 22 | AM_CPPFLAGS = 23 | if get_jit_size 24 | JIT_SIZE_PATH = "$(top_builddir)/jit_$(cpu)-sz.c" 25 | AM_CPPFLAGS += -DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)' 26 | endif 27 | if strong_type_checking 28 | AM_CPPFLAGS += -DSTRONG_TYPE_CHECKING=1 29 | endif 30 | 31 | liblightningdir = $(libdir) 32 | liblightning_la_SOURCES = \ 33 | jit_disasm.c \ 34 | jit_memory.c \ 35 | jit_note.c \ 36 | jit_print.c \ 37 | jit_size.c \ 38 | lightning.c 39 | 40 | EXTRA_DIST = \ 41 | jit_names.c \ 42 | jit_fallback.c \ 43 | jit_rewind.c \ 44 | aarch64-logical-immediates.c \ 45 | jit_aarch64.c \ 46 | jit_aarch64-cpu.c \ 47 | jit_aarch64-fpu.c \ 48 | jit_aarch64-sz.c \ 49 | jit_alpha.c \ 50 | jit_alpha-cpu.c \ 51 | jit_alpha-fpu.c \ 52 | jit_alpha-sz.c \ 53 | jit_arm.c \ 54 | jit_arm-cpu.c \ 55 | jit_arm-swf.c \ 56 | jit_arm-vfp.c \ 57 | jit_arm-sz.c \ 58 | jit_hppa.c \ 59 | jit_hppa-cpu.c \ 60 | jit_hppa-fpu.c \ 61 | jit_hppa-sz.c \ 62 | jit_ia64.c \ 63 | jit_ia64-cpu.c \ 64 | jit_ia64-fpu.c \ 65 | jit_ia64-sz.c \ 66 | jit_loongarch.c \ 67 | jit_loongarch-cpu.c \ 68 | jit_loongarch-fpu.c \ 69 | jit_loongarch-sz.c \ 70 | jit_mips.c \ 71 | jit_mips-cpu.c \ 72 | jit_mips-fpu.c \ 73 | jit_mips-sz.c \ 74 | jit_ppc.c \ 75 | jit_ppc-cpu.c \ 76 | jit_ppc-fpu.c \ 77 | jit_ppc-sz.c \ 78 | jit_riscv.c \ 79 | jit_riscv-cpu.c \ 80 | jit_riscv-fpu.c \ 81 | jit_riscv-sz.c \ 82 | jit_s390.c \ 83 | jit_s390-cpu.c \ 84 | jit_s390-fpu.c \ 85 | jit_s390-sz.c \ 86 | jit_sparc.c \ 87 | jit_sparc-cpu.c \ 88 | jit_sparc-fpu.c \ 89 | jit_sparc-sz.c \ 90 | jit_x86.c \ 91 | jit_x86-cpu.c \ 92 | jit_x86-sse.c \ 93 | jit_x86-x87.c \ 94 | jit_x86-sz.c 95 | -------------------------------------------------------------------------------- /lightning/lightning.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: GNU Lightning 7 | Description: JIT library 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -llightning 10 | Cflags: -I${includedir}/ 11 | 12 | 13 | -------------------------------------------------------------------------------- /lightning/m4/.gitignore: -------------------------------------------------------------------------------- 1 | /lt~obsolete.m4 2 | /ltversion.m4 3 | /ltsugar.m4 4 | /ltoptions.m4 5 | /libtool.m4 6 | /00gnulib.m4 7 | /gnulib-common.m4 8 | /gnulib-comp.m4 9 | /gnulib-tool.m4 10 | /zzgnulib.m4 11 | -------------------------------------------------------------------------------- /lightning/m4/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/parallel-rsp/fd28f47a96370c8bfcf41d680d1ab01879a801a8/lightning/m4/.gitkeep -------------------------------------------------------------------------------- /lightning/m4/gnulib-cache.m4: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2002-2021 Free Software Foundation, Inc. 2 | # 3 | # This file is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This file is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this file. If not, see . 15 | # 16 | # As a special exception to the GNU General Public License, 17 | # this file may be distributed as part of a program that 18 | # contains a configuration script generated by Autoconf, under 19 | # the same distribution terms as the rest of that program. 20 | # 21 | # Generated by gnulib-tool. 22 | # 23 | # This file represents the specification of how gnulib-tool is used. 24 | # It acts as a cache: It is written and read by gnulib-tool. 25 | # In projects that use version control, this file is meant to be put under 26 | # version control, like the configure.ac and various Makefile.am files. 27 | 28 | 29 | # Specification in the form of a command-line invocation: 30 | # gnulib-tool --import --local-dir=gl \ 31 | # --lib=libgnu \ 32 | # --source-base=gnulib-lib \ 33 | # --m4-base=m4 \ 34 | # --doc-base=gnulib-doc \ 35 | # --tests-base=tests \ 36 | # --aux-dir=build-aux \ 37 | # --no-conditional-dependencies \ 38 | # --libtool \ 39 | # --macro-prefix=gl 40 | 41 | # Specification in the form of a few gnulib-tool.m4 macro invocations: 42 | gl_LOCAL_DIR([gl]) 43 | gl_MODULES([ 44 | 45 | ]) 46 | gl_AVOID([]) 47 | gl_SOURCE_BASE([gnulib-lib]) 48 | gl_M4_BASE([m4]) 49 | gl_PO_BASE([]) 50 | gl_DOC_BASE([gnulib-doc]) 51 | gl_TESTS_BASE([tests]) 52 | gl_LIB([libgnu]) 53 | gl_MAKEFILE_NAME([]) 54 | gl_LIBTOOL 55 | gl_MACRO_PREFIX([gl]) 56 | gl_PO_DOMAIN([]) 57 | gl_WITNESS_C_MACRO([]) 58 | -------------------------------------------------------------------------------- /llvm_jit.hpp: -------------------------------------------------------------------------------- 1 | #ifndef JIT_HPP 2 | #define JIT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace JIT 9 | { 10 | using Func = void (*)(void *, void *); 11 | class LLVMEngine 12 | { 13 | public: 14 | LLVMEngine(const std::unordered_map &symbol_table); 15 | ~LLVMEngine(); 16 | 17 | private: 18 | friend class Block; 19 | struct Impl; 20 | std::unique_ptr impl; 21 | }; 22 | 23 | class Block 24 | { 25 | public: 26 | Block(LLVMEngine &engine); 27 | ~Block(); 28 | bool compile(uint64_t hash, const std::string &source); 29 | Func get_func() const 30 | { 31 | return block; 32 | } 33 | 34 | private: 35 | struct Impl; 36 | std::unique_ptr impl; 37 | Func block = nullptr; 38 | size_t block_size = 0; 39 | }; 40 | } // namespace JIT 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /rsp/cp2.cpp: -------------------------------------------------------------------------------- 1 | #include "../state.hpp" 2 | 3 | extern "C" 4 | { 5 | 6 | void RSP_CFC2(RSP::CPUState *rsp, unsigned rt, unsigned rd) 7 | { 8 | unsigned src = rd & 3; 9 | if (src == 3) 10 | src = 2; 11 | 12 | int16_t res = rsp_get_flags(rsp->cp2.flags[src].e); 13 | if (rt) 14 | rsp->sr[rt] = res; 15 | } 16 | 17 | void RSP_CTC2(RSP::CPUState *rsp, unsigned rt, unsigned rd) 18 | { 19 | rt = rsp->sr[rt] & 0xffff; 20 | 21 | unsigned dst = rd & 3; 22 | if (dst >= 2) 23 | { 24 | rt &= 0xff; 25 | dst = 2; 26 | } 27 | rsp_set_flags(rsp->cp2.flags[dst].e, rt); 28 | } 29 | 30 | void RSP_MTC2(RSP::CPUState *rsp, unsigned rt, unsigned rd, unsigned element) 31 | { 32 | #ifdef INTENSE_DEBUG 33 | fprintf(stderr, "MTC2, rt = %u, [rt] = 0x%x, rd = %u, e = %u\n", rt, rsp->sr[rt], rd, element); 34 | #endif 35 | 36 | uint16_t *e = rsp->cp2.regs[rd].e; 37 | const uint16_t v = rsp->sr[rt]; 38 | if (element & 1) 39 | { 40 | const auto i = element >> 1; 41 | e[i] = (e[i] & 0xff00) | (v >> 8); 42 | if (element != 0xf) 43 | e[i+1] = (e[i+1] & 0xff) | (v << 8); 44 | } 45 | else 46 | e[element >> 1] = v; 47 | } 48 | 49 | void RSP_MFC2(RSP::CPUState *rsp, unsigned rt, unsigned rd, unsigned element) 50 | { 51 | if (rt == 0) 52 | return; 53 | 54 | const uint16_t *e = rsp->cp2.regs[rd].e; 55 | unsigned lo = element >> 1; 56 | 57 | if (element & 1) 58 | { 59 | unsigned hi = ((element + 1) >> 1) & 7; 60 | uint16_t high = e[lo] << 8; 61 | uint8_t low = e[hi] >> 8; 62 | rsp->sr[rt] = int16_t(high | low); 63 | } 64 | else 65 | rsp->sr[rt] = int16_t(e[lo]); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /rsp/pipeline.h: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/pipeline.h: RSP processor pipeline. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __rsp_pipeline_h__ 12 | #define __rsp_pipeline_h__ 13 | #include "rsp/cp2.h" 14 | #include "rsp/decoder.h" 15 | #include "rsp/rsp.h" 16 | 17 | struct rsp; 18 | 19 | enum rsp_mem_request_type 20 | { 21 | RSP_MEM_REQUEST_NONE, 22 | RSP_MEM_REQUEST_INT_MEM, 23 | RSP_MEM_REQUEST_VECTOR, 24 | RSP_MEM_REQUEST_FOURTH, 25 | RSP_MEM_REQUEST_HALF, 26 | RSP_MEM_REQUEST_PACK, 27 | RSP_MEM_REQUEST_QUAD, 28 | RSP_MEM_REQUEST_REST, 29 | RSP_MEM_REQUEST_UPACK 30 | }; 31 | 32 | struct rsp_int_mem_packet 33 | { 34 | uint32_t data; 35 | uint32_t rdqm; 36 | uint32_t wdqm; 37 | 38 | unsigned rshift; 39 | }; 40 | 41 | struct rsp_vect_mem_packet 42 | { 43 | union aligned_rsp_1vect_t vdqm; 44 | 45 | void (*vldst_func)(struct rsp *rsp, uint32_t addr, unsigned element, uint16_t *regp, rsp_vect_t reg, 46 | rsp_vect_t dqm); 47 | 48 | unsigned element; 49 | unsigned dest; 50 | }; 51 | 52 | union rsp_mem_packet { 53 | struct rsp_int_mem_packet p_int; 54 | struct rsp_vect_mem_packet p_vect; 55 | }; 56 | 57 | struct rsp_mem_request 58 | { 59 | uint32_t addr; 60 | enum rsp_mem_request_type type; 61 | union rsp_mem_packet packet; 62 | }; 63 | 64 | struct rsp_latch 65 | { 66 | uint32_t pc; 67 | }; 68 | 69 | struct rsp_result 70 | { 71 | uint32_t result; 72 | unsigned dest; 73 | }; 74 | 75 | struct rsp_ifrd_latch 76 | { 77 | struct rsp_latch common; 78 | struct rsp_opcode opcode; 79 | uint32_t pc, iw; 80 | }; 81 | 82 | struct rsp_rdex_latch 83 | { 84 | struct rsp_latch common; 85 | struct rsp_opcode opcode; 86 | uint32_t iw; 87 | }; 88 | 89 | struct rsp_exdf_latch 90 | { 91 | struct rsp_latch common; 92 | struct rsp_result result; 93 | 94 | struct rsp_mem_request request; 95 | }; 96 | 97 | struct rsp_dfwb_latch 98 | { 99 | struct rsp_latch common; 100 | struct rsp_result result; 101 | }; 102 | 103 | struct rsp_pipeline 104 | { 105 | struct rsp_dfwb_latch dfwb_latch; 106 | struct rsp_exdf_latch exdf_latch; 107 | struct rsp_rdex_latch rdex_latch; 108 | struct rsp_ifrd_latch ifrd_latch; 109 | }; 110 | 111 | cen64_cold void rsp_pipeline_init(struct rsp_pipeline *pipeline); 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /rsp/reciprocal.h: -------------------------------------------------------------------------------- 1 | // 2 | // common/reciprocal.h: RSP reciprocal ROM contents. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef __common_reciprocal_h__ 12 | #define __common_reciprocal_h__ 13 | #include 14 | 15 | extern const uint16_t rsp_reciprocal_rom[1024]; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /rsp/registers.md: -------------------------------------------------------------------------------- 1 | // 2 | // rsp/registers.md: RSP register enumerations. 3 | // 4 | // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 | // Copyright (C) 2015, Tyler J. Stachecki. 6 | // 7 | // This file is subject to the terms and conditions defined in 8 | // 'LICENSE', which is part of this source code package. 9 | // 10 | 11 | #ifndef SP_REGISTER_LIST 12 | #define SP_REGISTER_LIST \ 13 | X(SP_MEM_ADDR_REG) \ 14 | X(SP_DRAM_ADDR_REG) \ 15 | X(SP_RD_LEN_REG) \ 16 | X(SP_WR_LEN_REG) \ 17 | X(SP_STATUS_REG) \ 18 | X(SP_DMA_FULL_REG) \ 19 | X(SP_DMA_BUSY_REG) \ 20 | X(SP_SEMAPHORE_REG) \ 21 | X(CMD_START) \ 22 | X(CMD_END) \ 23 | X(CMD_CURRENT) \ 24 | X(CMD_STATUS) \ 25 | X(CMD_CLOCK) \ 26 | X(CMD_BUSY) \ 27 | X(CMD_PIPE_BUSY) \ 28 | X(CMD_TMEM_BUSY) \ 29 | X(SP_PC_REG) \ 30 | X(SP_IBIST_REG) 31 | #endif 32 | 33 | SP_REGISTER_LIST 34 | 35 | -------------------------------------------------------------------------------- /rsp_disasm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RSP_DISASM_HPP_ 2 | #define RSP_DISASM_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace RSP 8 | { 9 | std::string disassemble(uint32_t pc, uint32_t instr); 10 | const char *register_name(unsigned reg_index); 11 | } 12 | 13 | #endif -------------------------------------------------------------------------------- /rsp_op.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RSP_OP_HPP__ 2 | #define RSP_OP_HPP__ 3 | 4 | #include "state.hpp" 5 | 6 | extern "C" 7 | { 8 | int RSP_MFC0(RSP::CPUState *rsp, unsigned rt, unsigned rd); 9 | int RSP_MTC0(RSP::CPUState *rsp, unsigned rd, unsigned rt); 10 | 11 | void RSP_MTC2(RSP::CPUState *rsp, unsigned rt, unsigned vd, unsigned e); 12 | void RSP_MFC2(RSP::CPUState *rsp, unsigned rt, unsigned vs, unsigned e); 13 | void RSP_CFC2(RSP::CPUState *rsp, unsigned rt, unsigned rd); 14 | void RSP_CTC2(RSP::CPUState *rsp, unsigned rt, unsigned rd); 15 | 16 | void RSP_CALL(void *opaque, unsigned target, unsigned ret); 17 | void RSP_RETURN(void *opaque, unsigned pc); 18 | void RSP_EXIT(void *opaque, int mode); 19 | void RSP_REPORT_PC(void *rsp, unsigned pc, unsigned instr); 20 | 21 | #define DECL_LS(op) void RSP_##op(RSP::CPUState *rsp, unsigned rt, unsigned element, int offset, unsigned base) 22 | 23 | DECL_LS(LBV); 24 | DECL_LS(LSV); 25 | DECL_LS(LLV); 26 | DECL_LS(LDV); 27 | DECL_LS(LQV); 28 | DECL_LS(LRV); 29 | DECL_LS(LPV); 30 | DECL_LS(LUV); 31 | DECL_LS(LHV); 32 | DECL_LS(LFV); 33 | DECL_LS(LWV); 34 | DECL_LS(LTV); 35 | 36 | DECL_LS(SBV); 37 | DECL_LS(SSV); 38 | DECL_LS(SLV); 39 | DECL_LS(SDV); 40 | DECL_LS(SQV); 41 | DECL_LS(SRV); 42 | DECL_LS(SPV); 43 | DECL_LS(SUV); 44 | DECL_LS(SHV); 45 | DECL_LS(SFV); 46 | DECL_LS(SWV); 47 | DECL_LS(STV); 48 | 49 | #define DECL_COP2(op) void RSP_##op(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 50 | DECL_COP2(VMULF); 51 | DECL_COP2(VMULU); 52 | DECL_COP2(VRNDP); 53 | DECL_COP2(VMULQ); 54 | DECL_COP2(VMUDL); 55 | DECL_COP2(VMUDM); 56 | DECL_COP2(VMUDN); 57 | DECL_COP2(VMUDH); 58 | DECL_COP2(VMACF); 59 | DECL_COP2(VMACU); 60 | DECL_COP2(VRNDN); 61 | DECL_COP2(VMACQ); 62 | DECL_COP2(VMADL); 63 | DECL_COP2(VMADM); 64 | DECL_COP2(VMADN); 65 | DECL_COP2(VMADH); 66 | DECL_COP2(VADD); 67 | DECL_COP2(VSUB); 68 | DECL_COP2(VABS); 69 | DECL_COP2(VADDC); 70 | DECL_COP2(VSUBC); 71 | DECL_COP2(VSAR); 72 | DECL_COP2(VLT); 73 | DECL_COP2(VEQ); 74 | DECL_COP2(VNE); 75 | DECL_COP2(VGE); 76 | DECL_COP2(VCL); 77 | DECL_COP2(VCH); 78 | DECL_COP2(VCR); 79 | DECL_COP2(VMRG); 80 | DECL_COP2(VAND); 81 | DECL_COP2(VNAND); 82 | DECL_COP2(VOR); 83 | DECL_COP2(VNOR); 84 | DECL_COP2(VXOR); 85 | DECL_COP2(VNXOR); 86 | DECL_COP2(VRCP); 87 | DECL_COP2(VRCPL); 88 | DECL_COP2(VRCPH); 89 | DECL_COP2(VMOV); 90 | DECL_COP2(VRSQ); 91 | DECL_COP2(VRSQL); 92 | DECL_COP2(VRSQH); 93 | DECL_COP2(VNOP); 94 | DECL_COP2(RESERVED); 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /rsp_vu_fuzzer.cpp: -------------------------------------------------------------------------------- 1 | #include "rsp_op.hpp" 2 | #include "rsp_disasm.hpp" 3 | #include 4 | 5 | using namespace RSP; 6 | 7 | static uint64_t hash_registers(const CPUState *rsp) 8 | { 9 | uint64_t h = 0xcbf29ce484222325ull; 10 | auto *data = reinterpret_cast(&rsp->cp2); 11 | unsigned words = sizeof(rsp->cp2) >> 2; 12 | for (size_t i = 0; i < words; i++) 13 | h = (h * 0x100000001b3ull) ^ data[i]; 14 | 15 | return h; 16 | } 17 | 18 | static void fill_cp2_register_state(std::mt19937 &rnd, CPUState *rsp) 19 | { 20 | auto *data = reinterpret_cast(&rsp->cp2); 21 | unsigned words = sizeof(rsp->cp2) >> 2; 22 | for (unsigned i = 0; i < words; i++) 23 | data[i] = rnd(); 24 | } 25 | 26 | static void run_vu_opcode(std::mt19937 &rnd, CPUState *rsp, unsigned instr) 27 | { 28 | fill_cp2_register_state(rnd, rsp); 29 | 30 | uint32_t op = instr & 63; 31 | uint32_t vd = (instr >> 6) & 31; 32 | uint32_t vs = (instr >> 11) & 31; 33 | uint32_t vt = (instr >> 16) & 31; 34 | uint32_t e = (instr >> 21) & 15; 35 | 36 | using VUOp = void (*)(RSP::CPUState *, unsigned vd, unsigned vs, unsigned vt, unsigned e); 37 | static const VUOp ops[64] = { 38 | RSP_VMULF, RSP_VMULU, nullptr, nullptr, RSP_VMUDL, RSP_VMUDM, RSP_VMUDN, RSP_VMUDH, RSP_VMACF, RSP_VMACU, nullptr, 39 | nullptr, RSP_VMADL, RSP_VMADM, RSP_VMADN, RSP_VMADH, RSP_VADD, RSP_VSUB, nullptr, RSP_VABS, RSP_VADDC, RSP_VSUBC, 40 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, RSP_VSAR, nullptr, nullptr, RSP_VLT, 41 | RSP_VEQ, RSP_VNE, RSP_VGE, RSP_VCL, RSP_VCH, RSP_VCR, RSP_VMRG, RSP_VAND, RSP_VNAND, RSP_VOR, RSP_VNOR, 42 | RSP_VXOR, RSP_VNXOR, nullptr, nullptr, RSP_VRCP, RSP_VRCPL, RSP_VRCPH, RSP_VMOV, RSP_VRSQ, RSP_VRSQL, RSP_VRSQH, 43 | RSP_VNOP, 44 | }; 45 | 46 | auto *vuop = ops[op]; 47 | if (!vuop) 48 | vuop = RSP_RESERVED; 49 | 50 | vuop(rsp, vd, vs, vt, e); 51 | 52 | uint64_t register_hash = hash_registers(rsp); 53 | auto disasm = disassemble(0, instr | (0x25u << 25u)); 54 | printf("%s (%llx)\n", disasm.c_str(), static_cast(register_hash)); 55 | } 56 | 57 | int main() 58 | { 59 | // Exhaustive test every single VU opcode with random input. 60 | std::mt19937 rnd(0xf00b4); // Fixed seed. 61 | CPUState state = {}; 62 | 63 | // Sweep through every opcode at least once. 64 | constexpr unsigned num_opcodes = 1u << 25u; 65 | for (unsigned instr = 0; instr < num_opcodes; instr++) 66 | run_vu_opcode(rnd, &state, instr); 67 | 68 | // Try random opcodes some more, should hopefully hit some interesting corner cases eventually. 69 | constexpr unsigned num_random_opcodes = 50000000; 70 | for (unsigned i = 0; i < num_random_opcodes; i++) 71 | { 72 | unsigned instr = rnd() & (num_opcodes - 1); 73 | run_vu_opcode(rnd, &state, instr); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /win32/mman/sys/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | mman.VC.db -------------------------------------------------------------------------------- /win32/mman/sys/.gitrepo: -------------------------------------------------------------------------------- 1 | ; DO NOT EDIT (unless you know what you are doing) 2 | ; 3 | ; This subdirectory is a git "subrepo", and this file is maintained by the 4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme 5 | ; 6 | [subrepo] 7 | remote = https://github.com/witwall/mman-win32.git 8 | branch = master 9 | commit = 2d1c576e62b99e85d99407e1a88794c6e44c3310 10 | parent = 9f797430963d9cf0fcef7d963466f9cac7026de2 11 | method = merge 12 | cmdver = 0.4.0 13 | -------------------------------------------------------------------------------- /win32/mman/sys/.vs/mman/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/parallel-rsp/fd28f47a96370c8bfcf41d680d1ab01879a801a8/win32/mman/sys/.vs/mman/v14/.suo -------------------------------------------------------------------------------- /win32/mman/sys/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project (mman-win32 C) 2 | 3 | cmake_minimum_required (VERSION 2.8) 4 | 5 | option (BUILD_SHARED_LIBS "shared/static libs" ON) 6 | option (BUILD_TESTS "tests?" OFF) 7 | 8 | set (headers mman.h) 9 | set (sources mman.c) 10 | 11 | add_library (mman ${sources}) 12 | 13 | if (BUILD_SHARED_LIBS) 14 | target_compile_definitions(mman 15 | PUBLIC MMAN_LIBRARY_DLL 16 | PRIVATE MMAN_LIBRARY 17 | ) 18 | endif() 19 | 20 | install (TARGETS mman RUNTIME DESTINATION bin 21 | LIBRARY DESTINATION lib${LIB_SUFFIX} 22 | ARCHIVE DESTINATION lib${LIB_SUFFIX}) 23 | 24 | install (FILES ${headers} DESTINATION include/sys) 25 | 26 | if (BUILD_TESTS) 27 | enable_testing () 28 | add_executable (t_mman test.c) 29 | target_link_libraries (t_mman mman) 30 | add_test (NAME t_mman COMMAND t_mman${CMAKE_EXECUTABLE_SUFFIX}) 31 | endif () 32 | 33 | 34 | -------------------------------------------------------------------------------- /win32/mman/sys/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # mman-win32 (mingw32) Makefile 3 | # 4 | include config.mak 5 | 6 | CFLAGS=-Wall -O3 -fomit-frame-pointer 7 | 8 | ifeq ($(BUILD_STATIC),yes) 9 | TARGETS+=libmman.a 10 | INSTALL+=static-install 11 | endif 12 | 13 | ifeq ($(BUILD_SHARED),yes) 14 | TARGETS+=libmman.dll 15 | INSTALL+=shared-install 16 | CFLAGS+=-DMMAN_LIBRARY_DLL -DMMAN_LIBRARY 17 | endif 18 | 19 | ifeq ($(BUILD_MSVC),yes) 20 | SHFLAGS+=-Wl,--output-def,libmman.def 21 | INSTALL+=lib-install 22 | endif 23 | 24 | all: $(TARGETS) 25 | 26 | mman.o: mman.c mman.h 27 | $(CC) -o mman.o -c mman.c $(CFLAGS) 28 | 29 | libmman.a: mman.o 30 | $(AR) cru libmman.a mman.o 31 | $(RANLIB) libmman.a 32 | 33 | libmman.dll: mman.o 34 | $(CC) -shared -o libmman.dll mman.o -Wl,--out-implib,libmman.dll.a 35 | 36 | header-install: 37 | mkdir -p $(DESTDIR)$(incdir) 38 | cp mman.h $(DESTDIR)$(incdir) 39 | 40 | static-install: header-install 41 | mkdir -p $(DESTDIR)$(libdir) 42 | cp libmman.a $(DESTDIR)$(libdir) 43 | 44 | shared-install: header-install 45 | mkdir -p $(DESTDIR)$(libdir) 46 | cp libmman.dll.a $(DESTDIR)$(libdir) 47 | mkdir -p $(DESTDIR)$(bindir) 48 | cp libmman.dll $(DESTDIR)$(bindir) 49 | 50 | lib-install: 51 | mkdir -p $(DESTDIR)$(libdir) 52 | cp libmman.lib $(DESTDIR)$(libdir) 53 | 54 | install: $(INSTALL) 55 | 56 | test.exe: test.c mman.c mman.h 57 | $(CC) -o test.exe test.c -L. -lmman 58 | 59 | test: $(TARGETS) test.exe 60 | test.exe 61 | 62 | clean:: 63 | rm -f mman.o libmman.a libmman.dll.a libmman.dll libmman.def libmman.lib test.exe *.dat 64 | 65 | distclean: clean 66 | rm -f config.mak 67 | 68 | .PHONY: clean distclean install test 69 | -------------------------------------------------------------------------------- /win32/mman/sys/README.md: -------------------------------------------------------------------------------- 1 | mman-win32 2 | ========== 3 | 4 | mman library for Windows. mirror of https://code.google.com/p/mman-win32/ 5 | 6 | A light implementation of the mmap functions for MinGW. 7 | 8 | The mmap-win32 library implements a wrapper for mmap functions around the memory mapping Windows API. 9 | 10 | License: MIT License 11 | -------------------------------------------------------------------------------- /win32/mman/sys/UpgradeLog.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/parallel-rsp/fd28f47a96370c8bfcf41d680d1ab01879a801a8/win32/mman/sys/UpgradeLog.htm -------------------------------------------------------------------------------- /win32/mman/sys/mman-win32.pro: -------------------------------------------------------------------------------- 1 | QT -= core gui 2 | 3 | TARGET = mman 4 | TEMPLATE = lib 5 | 6 | DEFINES += MMAN_LIBRARY_DLL 7 | DEFINES += MMAN_LIBRARY 8 | 9 | HEADERS += \ 10 | mman.h 11 | 12 | SOURCES += \ 13 | mman.c 14 | -------------------------------------------------------------------------------- /win32/mman/sys/mman.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys/mman.h 3 | * mman-win32 4 | */ 5 | 6 | #ifndef _SYS_MMAN_H_ 7 | #define _SYS_MMAN_H_ 8 | 9 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. 10 | #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. 11 | #endif 12 | 13 | /* All the headers include this file. */ 14 | #ifndef _MSC_VER 15 | #include <_mingw.h> 16 | #endif 17 | 18 | #if defined(MMAN_LIBRARY_DLL) 19 | /* Windows shared libraries (DLL) must be declared export when building the lib and import when building the 20 | application which links against the library. */ 21 | #if defined(MMAN_LIBRARY) 22 | #define MMANSHARED_EXPORT __declspec(dllexport) 23 | #else 24 | #define MMANSHARED_EXPORT __declspec(dllimport) 25 | #endif /* MMAN_LIBRARY */ 26 | #else 27 | /* Static libraries do not require a __declspec attribute.*/ 28 | #define MMANSHARED_EXPORT 29 | #endif /* MMAN_LIBRARY_DLL */ 30 | 31 | /* Determine offset type */ 32 | #include 33 | #if defined(_WIN64) 34 | typedef int64_t OffsetType; 35 | #else 36 | typedef uint32_t OffsetType; 37 | #endif 38 | 39 | #include 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | #define PROT_NONE 0 46 | #define PROT_READ 1 47 | #define PROT_WRITE 2 48 | #define PROT_EXEC 4 49 | 50 | #define MAP_FILE 0 51 | #define MAP_SHARED 1 52 | #define MAP_PRIVATE 2 53 | #define MAP_TYPE 0xf 54 | #define MAP_FIXED 0x10 55 | #define MAP_ANONYMOUS 0x20 56 | #define MAP_ANON MAP_ANONYMOUS 57 | 58 | #define MAP_FAILED ((void *)-1) 59 | 60 | /* Flags for msync. */ 61 | #define MS_ASYNC 1 62 | #define MS_SYNC 2 63 | #define MS_INVALIDATE 4 64 | 65 | MMANSHARED_EXPORT void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off); 66 | MMANSHARED_EXPORT int munmap(void *addr, size_t len); 67 | MMANSHARED_EXPORT int _mprotect(void *addr, size_t len, int prot); 68 | MMANSHARED_EXPORT int msync(void *addr, size_t len, int flags); 69 | MMANSHARED_EXPORT int mlock(const void *addr, size_t len); 70 | MMANSHARED_EXPORT int munlock(const void *addr, size_t len); 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif /* _SYS_MMAN_H_ */ 77 | -------------------------------------------------------------------------------- /win32/mman/sys/mman.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mman", "mman.vcxproj", "{592F578E-6F24-47C0-9F6C-07BC9B730E27}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x64.ActiveCfg = Debug|x64 17 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x64.Build.0 = Debug|x64 18 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x86.ActiveCfg = Debug|Win32 19 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x86.Build.0 = Debug|Win32 20 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x64.ActiveCfg = Release|x64 21 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x64.Build.0 = Release|x64 22 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x86.ActiveCfg = Release|Win32 23 | {592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /win32/mman/sys/mman.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /win32/mman/sys/mman.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------