1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-11 22:31:12 +02:00

Add several arithmetic and branch tests cases.

* check/alu.inc, check/alu_add.ok, check/alu_add.tst,
	check/alu_and.ok, check/alu_and.tst, check/alu_com.ok,
	check/alu_com.tst, check/alu_div.ok, check/alu_div.tst,
	check/alu_lsh.ok, check/alu_lsh.tst, check/alu_mul.ok,
	check/alu_mul.tst, check/alu_neg.ok, check/alu_neg.tst,
	check/alu_or.ok, check/alu_or.tst, check/alu_rem.ok,
	check/alu_rem.tst, check/alu_rsh.ok, check/alu_rsh.tst,
	check/alu_sub.ok, check/alu_sub.tst, check/alu_xor.ok,
	check/alu_xor.tst, check/alux_add.ok, check/alux_add.tst,
	check/alux_sub.ok, check/alux_sub.tst, check/branch.ok,
	check/branch.tst: New test cases for arithmetic and branch
	tests.

	* check/Makefile.am: Update for new test cases.

	* include/lightning/jit_private.h: Make the jit_reg_free_p
	macro shared by all backends. Previously was added for the
	arm backend, but is useful in the x86_64 backend when checking
	state of "special purpose register".
	Also add the new jit_class_named register class, that must be
	or'ed with the register value if calling jit_get_reg expecting
	an specific value, because the specific register value may be
	zero, that previously was treated as no register requested.

	* lib/jit_arm-cpu.c: Correct argument order for T2_MVN.

	* lib/jit_arm-swf.c: Call the proper function for double
	divide. The "software float" implementation just calls
	libgcc functions.

	* lib/jit_arm.c: Return float/double values in the float
	register if using the hard float ABI.

	* lib/jit_x86-cpu.c: Change the can_sign_extend_int_p macro
	to not include -0x80000000L, because there is code that
	"abuses" it and thinks it can negate the immediate value
	after calling that macro.
	  Correct implementation of jit_subi that had a wrong code
	patch logic doing subtraction with reversed arguments.
	  Correct REX prefix calculation in the jit_muli implementation.
	  Correct logic to get/unget %*ax and %*dx registers in divremr
	and divremi.
	  Correct divremi that was using the symbolic, unique %*ax
	value in on place (not using the _REGNO name suffix).
	  Correct cut&paste error causing it to use "xor" instead of
	"or" in one code path of the jit_ori implementation.
	  Correct several flaws when clobbering registers and/or when
	one of the arguments was %*cx in the rotshr wrapper function
	implementing most shift operations.

	* lib/lightning.c: No longer expect that the backend be smart
	enough to know what to do when asking for a named register
	if that register is already an argument or is live. It fails
	if it is an argument, or if register is live, fails if cannot
	spill.
	  No longer incorrectly assume that eqr_{f,d} and ltgr_{f,d} are
	safe to inverse value tests in jump thread optimization.
This commit is contained in:
pcpa 2012-12-09 19:13:33 -02:00
parent d1c0bc8e98
commit e255b76068
39 changed files with 1773 additions and 58 deletions

View file

@ -1,3 +1,63 @@
2012-12-09 Paulo Andrade <pcpa@gnu.org>
* check/alu.inc, check/alu_add.ok, check/alu_add.tst,
check/alu_and.ok, check/alu_and.tst, check/alu_com.ok,
check/alu_com.tst, check/alu_div.ok, check/alu_div.tst,
check/alu_lsh.ok, check/alu_lsh.tst, check/alu_mul.ok,
check/alu_mul.tst, check/alu_neg.ok, check/alu_neg.tst,
check/alu_or.ok, check/alu_or.tst, check/alu_rem.ok,
check/alu_rem.tst, check/alu_rsh.ok, check/alu_rsh.tst,
check/alu_sub.ok, check/alu_sub.tst, check/alu_xor.ok,
check/alu_xor.tst, check/alux_add.ok, check/alux_add.tst,
check/alux_sub.ok, check/alux_sub.tst, check/branch.ok,
check/branch.tst: New test cases for arithmetic and branch
tests.
* check/Makefile.am: Update for new test cases.
* include/lightning/jit_private.h: Make the jit_reg_free_p
macro shared by all backends. Previously was added for the
arm backend, but is useful in the x86_64 backend when checking
state of "special purpose register".
Also add the new jit_class_named register class, that must be
or'ed with the register value if calling jit_get_reg expecting
an specific value, because the specific register value may be
zero, that previously was treated as no register requested.
* lib/jit_arm-cpu.c: Correct argument order for T2_MVN.
* lib/jit_arm-swf.c: Call the proper function for double
divide. The "software float" implementation just calls
libgcc functions.
* lib/jit_arm.c: Return float/double values in the float
register if using the hard float ABI.
* lib/jit_x86-cpu.c: Change the can_sign_extend_int_p macro
to not include -0x80000000L, because there is code that
"abuses" it and thinks it can negate the immediate value
after calling that macro.
Correct implementation of jit_subi that had a wrong code
patch logic doing subtraction with reversed arguments.
Correct REX prefix calculation in the jit_muli implementation.
Correct logic to get/unget %*ax and %*dx registers in divremr
and divremi.
Correct divremi that was using the symbolic, unique %*ax
value in on place (not using the _REGNO name suffix).
Correct cut&paste error causing it to use "xor" instead of
"or" in one code path of the jit_ori implementation.
Correct several flaws when clobbering registers and/or when
one of the arguments was %*cx in the rotshr wrapper function
implementing most shift operations.
* lib/lightning.c: No longer expect that the backend be smart
enough to know what to do when asking for a named register
if that register is already an argument or is live. It fails
if it is an argument, or if register is live, fails if cannot
spill.
No longer incorrectly assume that eqr_{f,d} and ltgr_{f,d} are
safe to inverse value tests in jump thread optimization.
2012-12-05 Paulo Andrade <pcpa@gnu.org>
* check/Makefile.am, check/cvt.ok, check/cvt.tst: Add new

View file

@ -41,6 +41,22 @@ EXTRA_DIST = \
ldstxr-c.tst ldstxr-c.ok \
ldstxi-c.tst ldstxi-c.ok \
cvt.tst cvt.ok \
branch.tst branch.ok \
alu.inc \
alu_add.tst alu_add.ok \
alux_add.tst alux_add.ok \
alu_sub.tst alu_sub.ok \
alux_sub.tst alux_sub.ok \
alu_mul.tst alu_mul.ok \
alu_div.tst alu_div.ok \
alu_rem.tst alu_rem.ok \
alu_and.tst alu_and.ok \
alu_or.tst alu_or.ok \
alu_xor.tst alu_xor.ok \
alu_lsh.tst alu_lsh.ok \
alu_rsh.tst alu_rsh.ok \
alu_com.tst alu_com.ok \
alu_neg.tst alu_neg.ok \
check.sh run-test \
all.tst
@ -49,7 +65,13 @@ TESTS = 3to2 add allocai \
ldstr ldsti \
ldstxr ldstxi \
ldstr-c ldstxr-c ldstxi-c \
cvt
cvt branch \
alu_add alux_add \
alu_sub alux_sub \
alu_mul alu_div alu_rem \
alu_and alu_or alu_xor \
alu_lsh alu_rsh \
alu_com alu_neg
CLEANFILES = $(TESTS)

283
check/alu.inc Normal file
View file

@ -0,0 +1,283 @@
.data 8
ok:
.c "ok\n"
/* 3 operand */
/* reg0 = reg1 op reg2 */
#define ALUR(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R1 I0 \
movi %R2 I1 \
OP##r##T %R0 %R1 %R2 \
beqi OP##T##N##r_##R0##R1##R2 %R0 V \
calli @abort \
OP##T##N##r_##R0##R1##R2:
/* reg0 = reg1 op im */
#define ALUI(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R1 I0 \
movi %R2 V \
OP##i##T %R0 %R1 I1 \
beqr OP##T##N##i_##R0##R1##R2 %R0 %R2 \
calli @abort \
OP##T##N##i_##R0##R1##R2:
/* reg0 = reg0 op reg1 */
#define ALUR0(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R1 I1 \
movi %R2 V \
OP##r##T %R0 %R0 %R1 \
beqr OP##T##N##r_0##R0##R1##R2 %R0 %R2 \
calli @abort \
OP##T##N##r_0##R0##R1##R2:
/* reg0 = reg1 op reg0 */
#define ALUR1(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I1 \
movi %R1 I0 \
movi %R2 V \
OP##r##T %R0 %R1 %R0 \
beqr OP##T##N##r_1##R0##R1##R2 %R0 %R2 \
calli @abort \
OP##T##N##r_1##R0##R1##R2:
/* reg0 = reg0 op im */
#define ALUI0(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R1 V \
OP##i##T %R0 %R0 I1 \
beqr OP##T##N##i_0##R0##R1##R2 %R0 %R1 \
calli @abort \
OP##T##N##i_0##R0##R1##R2:
#define ALU3(N, T, OP, I0, I1, V, R0, R1, R2) \
ALUR(N, T, OP, I0, I1, V, R0, R1, R2) \
ALUI(N, T, OP, I0, I1, V, R0, R1, R2) \
ALUR0(N, T, OP, I0, I1, V, R0, R1, R2) \
ALUR1(N, T, OP, I0, I1, V, R0, R1, R2) \
ALUI0(N, T, OP, I0, I1, V, R0, R1, R2)
#define ALU2(N, T, OP, I0, I1, V, R0, R1, R2) \
ALU3(N, T, OP, I0, I1, V, R0, R1, R2) \
ALU3(N, T, OP, I0, I1, V, R0, R2, R1)
#define ALU1(N, T, OP, I0, I1, V, R0, R1, R2) \
ALU2(N, T, OP, I0, I1, V, R0, R1, R2) \
ALU2(N, T, OP, I0, I1, V, R1, R0, R2) \
ALU2(N, T, OP, I0, I1, V, R2, R1, R0)
#define ALU(N, T, OP, I0, I1, V) \
ALU1(N, T, OP, I0, I1, V, v0, v1, v2) \
ALU1(N, T, OP, I0, I1, V, v0, v1, r0) \
ALU1(N, T, OP, I0, I1, V, v0, v1, r1) \
ALU1(N, T, OP, I0, I1, V, v0, v1, r2) \
ALU1(N, T, OP, I0, I1, V, v1, v2, r1) \
ALU1(N, T, OP, I0, I1, V, v1, v2, r2) \
ALU1(N, T, OP, I0, I1, V, v2, r0, r1) \
ALU1(N, T, OP, I0, I1, V, v2, r0, r2) \
ALU1(N, T, OP, I0, I1, V, r0, r1, r2)
/* 3 carry set/propagate */
/*
* r0 = i0
* r1 = i1
* r2 = 0
* r0 = r0 opc r1 <only want carry>
* r2 = r2 opx r2 <r2 must match v>
*/
#define ALUXII(N, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R2 0 \
OP##ci %R0 %R0 I1 \
OP##xi %R2 %R2 0 \
beqi OP##N##ii##R0##R1##R2 %R2 V \
calli @abort \
OP##N##ii##R0##R1##R2:
#define ALUXIR(N, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R2 0 \
OP##ci %R0 %R0 I1 \
OP##xr %R2 %R2 %R2 \
beqi OP##N##ir##R0##R1##R2 %R2 V \
calli @abort \
OP##N##ir##R0##R1##R2:
#define ALUXRI(N, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R1 I1 \
movi %R2 0 \
OP##cr %R0 %R0 %R1 \
OP##xi %R2 %R2 0 \
beqi OP##N##ri##R0##R1##R2 %R2 V \
calli @abort \
OP##N##ri##R0##R1##R2:
#define ALUXRR(N, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I0 \
movi %R1 I1 \
movi %R2 0 \
OP##cr %R0 %R0 %R1 \
OP##xr %R2 %R2 %R2 \
beqi OP##N##rr##R0##R1##R2 %R2 V \
calli @abort \
OP##N##rr##R0##R1##R2:
#define ALUX2(N, OP, I0, I1, V, R0, R1, R2) \
ALUXII(N, OP, I0, I1, V, R0, R1, R2) \
ALUXIR(N, OP, I0, I1, V, R0, R1, R2) \
ALUXRI(N, OP, I0, I1, V, R0, R1, R2) \
ALUXRR(N, OP, I0, I1, V, R0, R1, R2)
#define ALUX1(N, OP, I0, I1, V, R0, R1, R2) \
ALUX2(N, OP, I0, I1, V, R0, R1, R2) \
ALUX2(N, OP, I0, I1, V, R0, R2, R1)
#define ALUX0(N, OP, I0, I1, V, R0, R1, R2) \
ALUX1(N, OP, I0, I1, V, R0, R1, R2) \
ALUX1(N, OP, I0, I1, V, R1, R0, R2) \
ALUX1(N, OP, I0, I1, V, R2, R1, R0)
#define ALUX(N, OP, I0, I1, V) \
ALUX0(N, OP, I0, I1, V, v0, v1, v2) \
ALUX0(N, OP, I0, I1, V, v0, v1, r0) \
ALUX0(N, OP, I0, I1, V, v0, v1, r1) \
ALUX0(N, OP, I0, I1, V, v0, v1, r2) \
ALUX0(N, OP, I0, I1, V, v1, v2, r0) \
ALUX0(N, OP, I0, I1, V, v1, v2, r1) \
ALUX0(N, OP, I0, I1, V, v1, v2, r2) \
ALUX0(N, OP, I0, I1, V, v2, r0, r1) \
ALUX0(N, OP, I0, I1, V, v2, r0, r2) \
ALUX0(N, OP, I0, I1, V, r0, r1, r2)
/* unary int */
#define UNR(N, OP, I, V, R0, R1) \
movi %R1 I \
OP##r %R0 %R1 \
beqi OP##N##R0##R1 %R0 V \
calli @abort \
OP##N##R0##R1:
#define UNRC(N, OP, I, V, R0, R1) \
movi %R0 I \
OP##r %R0 %R0 \
beqi OP##N##c##R0##R1 %R0 V \
calli @abort \
OP##N##c##R0##R1:
#define UN2(N, OP, I, V, R0, R1) \
UNR(N, OP, I, V, R0, R1) \
UNRC(N, OP, I, V, R0, R1)
#define UN1(N, OP, I, V, R0, R1) \
UN2(N, OP, I, V, R0, R1) \
UN2(N, OP, I, V, R1, R0)
#define UN(N, OP, I, V) \
UN1(N, OP, I, V, v0, v1) \
UN1(N, OP, I, V, v0, v2) \
UN1(N, OP, I, V, v0, r0) \
UN1(N, OP, I, V, v0, r1) \
UN1(N, OP, I, V, v0, r2) \
UN1(N, OP, I, V, v1, v2) \
UN1(N, OP, I, V, v1, r0) \
UN1(N, OP, I, V, v1, r1) \
UN1(N, OP, I, V, v1, r2) \
UN1(N, OP, I, V, v2, r0) \
UN1(N, OP, I, V, v2, r1) \
UN1(N, OP, I, V, v2, r2) \
UN1(N, OP, I, V, r0, r1) \
UN1(N, OP, I, V, r0, r2) \
UN1(N, OP, I, V, r1, r2)
/* reg0 = reg1 op reg2 */
#define FOPR(N, T, OP, I0, I1, V, F0, F1, F2) \
movi##T %F1 I0 \
movi##T %F2 I1 \
OP##r##T %F0 %F1 %F2 \
beqi##T OP##T##N##F0##F1##F2 %F0 V \
calli @abort \
OP##T##N##F0##F1##F2:
/* reg0 = reg0 op reg1 */
#define FOPR0(N, T, OP, I0, I1, V, F0, F1, F2) \
movi##T %F0 I0 \
movi##T %F1 I1 \
OP##r##T %F0 %F0 %F1 \
beqi##T OP##T##N##0##F0##F1##F2 %F0 V \
calli @abort \
OP##T##N##0##F0##F1##F2:
/* reg1 = reg0 op reg1 */
#define FOPR1(N, T, OP, I0, I1, V, F0, F1, F2) \
movi##T %F0 I0 \
movi##T %F1 I1 \
OP##r##T %F1 %F0 %F1 \
beqi##T OP##T##N##1##F0##F1##F2 %F1 V \
calli @abort \
OP##T##N##1##F0##F1##F2:
/* reg0 = reg1 op im */
#define FOPI(N, T, OP, I0, I1, V, F0, F1, F2) \
movi##T %F1 I0 \
movi##T %F2 V \
OP##i##T %F0 %F1 I1 \
beqr##T OP##T##N##i##F0##F1##F2 %F0 %F2 \
calli @abort \
OP##T##N##i##F0##F1##F2:
/* reg0 = reg0 op im */
#define FOPI0(N, T, OP, I0, I1, V, F0, F1, F2) \
movi##T %F0 I0 \
movi##T %F2 V \
OP##i##T %F0 %F0 I1 \
beqr##T OP##T##N##i0##F0##F1##F2 %F0 %F2 \
calli @abort \
OP##T##N##i0##F0##F1##F2:
#define FOP1(N, T, OP, I0, I1, V, F0, F1, F2) \
FOPR(N, T, OP, I0, I1, V, F0, F1, F2) \
FOPR0(N, T, OP, I0, I1, V, F0, F1, F2) \
FOPR1(N, T, OP, I0, I1, V, F0, F1, F2) \
FOPI(N, T, OP, I0, I1, V, F0, F1, F2) \
FOPI0(N, T, OP, I0, I1, V, F0, F1, F2)
#define FOP(N, T, OP, I0, I1, V) \
FOP1(N, T, OP, I0, I1, V, f0, f1, f2) \
FOP1(N, T, OP, I0, I1, V, f0, f2, f3) \
FOP1(N, T, OP, I0, I1, V, f0, f3, f4) \
FOP1(N, T, OP, I0, I1, V, f0, f5, f1)
/* unary float */
#define FUNR(N, T, OP, I, V, R0, R1) \
movi##T %R1 I \
OP##r##T %R0 %R1 \
beqi##T OP##N##T##R0##R1 %R0 V \
calli @abort \
OP##N##T##R0##R1:
#define FUNRC(N, T, OP, I, V, R0, R1) \
movi##T %R0 I \
OP##r##T %R0 %R0 \
beqi##T OP##N##T##c##R0##R1 %R0 V \
calli @abort \
OP##N##T##c##R0##R1:
#define FUN2(N, T, OP, I, V, R0, R1) \
FUNR(N, T, OP, I, V, R0, R1) \
FUNRC(N, T, OP, I, V, R0, R1)
#define FUN1(N, T, OP, I, V, R0, R1) \
FUN2(N, T, OP, I, V, R0, R1) \
FUN2(N, T, OP, I, V, R1, R0)
#define FUN(N, T, OP, I, V) \
FUN1(N, T, OP, I, V, f0, f1) \
FUN1(N, T, OP, I, V, f0, f2) \
FUN1(N, T, OP, I, V, f0, f3) \
FUN1(N, T, OP, I, V, f0, f4) \
FUN1(N, T, OP, I, V, f0, f5)

1
check/alu_add.ok Normal file
View file

@ -0,0 +1 @@
ok

46
check/alu_add.tst Normal file
View file

@ -0,0 +1,46 @@
#include "alu.inc"
.code
prolog
#define ADD(N, I0, I1, V) ALU(N, , add, I0, I1, V)
ADD(0, 0x7fffffff, 1, 0x80000000)
ADD(1, 1, 0x7fffffff, 0x80000000)
ADD(2, 0x80000000, 1, 0x80000001)
ADD(3, 1, 0x80000000, 0x80000001)
ADD(4, 0x7fffffff, 0x80000000, 0xffffffff)
ADD(5, 0x80000000, 0x7fffffff, 0xffffffff)
ADD(6, 0x7fffffff, 0, 0x7fffffff)
ADD(7, 0, 0x7fffffff, 0x7fffffff)
#if __WORDSIZE == 32
ADD(8, 0x7fffffff, 0xffffffff, 0x7ffffffe)
ADD(9, 0xffffffff, 0x7fffffff, 0x7ffffffe)
ADD(10, 0xffffffff, 0xffffffff, 0xfffffffe)
#else
ADD(8, 0x7fffffff, 0xffffffff, 0x17ffffffe)
ADD(9, 0xffffffff, 0x7fffffff, 0x17ffffffe)
ADD(10, 0xffffffff, 0xffffffff, 0x1fffffffe)
ADD(11, 0x7fffffffffffffff, 1, 0x8000000000000000)
ADD(12, 1, 0x7fffffffffffffff, 0x8000000000000000)
ADD(13, 0x8000000000000000, 1, 0x8000000000000001)
ADD(14, 1, 0x8000000000000000, 0x8000000000000001)
ADD(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff)
ADD(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff)
ADD(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffffe)
ADD(18, 0x7fffffffffffffff, 0x7fffffffffffffff, 0xfffffffffffffffe)
ADD(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffffe)
#endif
#undef ADD
#define ADD(N, T, I0, I1, V) FOP(N, T, add, I0, I1, V)
ADD(0, _f, -0.5, 0.5, 0.0)
ADD(1, _f, 0.25, 0.75, 1.0)
ADD(0, _d, -0.5, 0.5, 0.0)
ADD(1, _d, 0.25, 0.75, 1.0)
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_and.ok Normal file
View file

@ -0,0 +1 @@
ok

35
check/alu_and.tst Normal file
View file

@ -0,0 +1,35 @@
#include "alu.inc"
.code
prolog
#define AND(N, I0, I1, V) ALU(N, , and, I0, I1, V)
AND(0, 0x7fffffff, 1, 1)
AND(1, 1, 0x7fffffff, 1)
AND(2, 0x80000000, 1, 0)
AND(3, 1, 0x80000000, 0)
AND(4, 0x7fffffff, 0x80000000, 0)
AND(5, 0x80000000, 0x7fffffff, 0)
AND(6, 0x7fffffff, 0xffffffff, 0x7fffffff)
AND(7, 0xffffffff, 0x7fffffff, 0x7fffffff)
AND(8, 0xffffffff, 0xffffffff, 0xffffffff)
AND(9, 0x7fffffff, 0, 0)
AND(10, 0, 0x7fffffff, 0)
#if __WORDSIZE == 64
AND(11, 0x7fffffffffffffff, 1, 1)
AND(12, 1, 0x7fffffffffffffff, 1)
AND(13, 0x8000000000000000, 1, 0)
AND(14, 1, 0x8000000000000000, 0)
AND(15, 0x7fffffffffffffff, 0x8000000000000000, 0)
AND(16, 0x8000000000000000, 0x7fffffffffffffff, 0)
AND(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff)
AND(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0x7fffffffffffffff)
AND(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_com.ok Normal file
View file

@ -0,0 +1 @@
ok

32
check/alu_com.tst Normal file
View file

@ -0,0 +1,32 @@
#include "alu.inc"
.code
prolog
#define COM(N, I0, V) UN(N, com, I0, V)
#if __WORDSIZE == 32
COM(0, 0, 0xffffffff)
COM(1, 1, 0xfffffffe)
COM(2, 0xffffffff, 0)
COM(3, 0x80000000, 0x7fffffff)
COM(4, 0x7fffffff, 0x80000000)
COM(5, 0x80000001, 0x7ffffffe)
#else
COM(0, 0, 0xffffffffffffffff)
COM(1, 1, 0xfffffffffffffffe)
COM(2, 0xffffffff, 0xffffffff00000000)
COM(3, 0x80000000, 0xffffffff7fffffff)
COM(4, 0x7fffffff, 0xffffffff80000000)
COM(5, 0x80000001, 0xffffffff7ffffffe)
COM(6, 0xffffffffffffffff, 0)
COM(7, 0x8000000000000000, 0x7fffffffffffffff)
COM(8, 0x7fffffffffffffff, 0x8000000000000000)
COM(9, 0x8000000000000001, 0x7ffffffffffffffe)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_div.ok Normal file
View file

@ -0,0 +1 @@
ok

82
check/alu_div.tst Normal file
View file

@ -0,0 +1,82 @@
#include "alu.inc"
.code
prolog
#define DIV(N, I0, I1, V) ALU(N, , div, I0, I1, V)
#define UDIV(N, I0, I1, V) ALU(N, _u, div, I0, I1, V)
DIV(0, 0x7fffffff, 1, 0x7fffffff)
DIV(1, 1, 0x7fffffff, 0)
DIV(2, 0x80000000, 1, 0x80000000)
DIV(3, 1, 0x80000000, 0)
DIV(4, 0x7fffffff, 2, 0x3fffffff)
DIV(5, 2, 0x7fffffff, 0)
DIV(6, 2, 0x80000000, 0)
DIV(7, 0x7fffffff, 0x80000000, 0)
DIV(8, 0, 0x7fffffff, 0)
DIV(9, 0xffffffff, 0xffffffff, 1)
UDIV(0, 0x7fffffff, 1, 0x7fffffff)
UDIV(1, 1, 0x7fffffff, 0)
UDIV(2, 0x80000000, 1, 0x80000000)
UDIV(3, 1, 0x80000000, 0)
UDIV(4, 0x7fffffff, 2, 0x3fffffff)
UDIV(5, 2, 0x7fffffff, 0)
UDIV(6, 0x80000000, 2, 0x40000000)
UDIV(7, 2, 0x80000000, 0)
UDIV(8, 0x7fffffff, 0x80000000, 0)
UDIV(9, 0x80000000, 0x7fffffff, 1)
UDIV(10,0, 0x7fffffff, 0)
UDIV(11,0x7fffffff, 0xffffffff, 0)
UDIV(12,0xffffffff, 0x7fffffff, 2)
UDIV(13,0xffffffff, 0xffffffff, 1)
#if __WORDSIZE == 32
DIV(10, 0x80000000, 2, 0xc0000000)
DIV(11, 0x80000000, 0x7fffffff, 0xffffffff)
DIV(12, 0x7fffffff, 0xffffffff, 0x80000001)
DIV(13, 0xffffffff, 0x7fffffff, 0)
#else
DIV(10, 0x80000000, 2, 0x40000000)
DIV(11, 0x80000000, 0x7fffffff, 1)
DIV(12, 0x7fffffff, 0xffffffff, 0)
DIV(13, 0xffffffff, 0x7fffffff, 2)
DIV(14, 0x7fffffffffffffff, 1, 0x7fffffffffffffff)
DIV(15, 1, 0x7fffffffffffffff, 0)
DIV(16, 0x8000000000000000, 1, 0x8000000000000000)
DIV(17, 1, 0x8000000000000000, 0)
DIV(18, 0x7fffffffffffffff, 2, 0x3fffffffffffffff)
DIV(19, 2, 0x7fffffffffffffff, 0)
DIV(20, 0x8000000000000000, 2, 0xc000000000000000)
DIV(21, 2, 0x8000000000000000, 0)
DIV(22, 0x7fffffffffffffff, 0x8000000000000000, 0)
DIV(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff)
DIV(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001)
DIV(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0)
DIV(26, 0xffffffffffffffff, 0xffffffffffffffff, 1)
UDIV(14,0x7fffffffffffffff, 1, 0x7fffffffffffffff)
UDIV(15,1, 0x7fffffffffffffff, 0)
UDIV(16,0x8000000000000000, 1, 0x8000000000000000)
UDIV(17,1, 0x8000000000000000, 0)
UDIV(18,0x7fffffffffffffff, 2, 0x3fffffffffffffff)
UDIV(19,2, 0x7fffffffffffffff, 0)
UDIV(20,0x8000000000000000, 2, 0x4000000000000000)
UDIV(21,2, 0x8000000000000000, 0)
UDIV(22,0x7fffffffffffffff, 0x8000000000000000, 0)
UDIV(23,0x8000000000000000, 0x7fffffffffffffff, 1)
UDIV(24,0x7fffffffffffffff, 0xffffffffffffffff, 0)
UDIV(25,0xffffffffffffffff, 0x7fffffffffffffff, 2)
UDIV(26,0xffffffffffffffff, 0xffffffffffffffff, 1)
#endif
#undef DIV
#define DIV(N, T, I0, I1, V) FOP(N, T, div, I0, I1, V)
DIV(0, _f, -0.5, 0.5, -1.0)
DIV(1, _f, 1.25, 0.5, 2.5)
DIV(0, _d, -0.5, 0.5, -1.0)
DIV(1, _d, 1.25, 0.5, 2.5)
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_lsh.ok Normal file
View file

@ -0,0 +1 @@
ok

56
check/alu_lsh.tst Normal file
View file

@ -0,0 +1,56 @@
#include "alu.inc"
.code
prolog
#define LSH(N, I0, I1, V) ALU(N, , lsh, I0, I1, V)
LSH(0, 0x7f, 1, 0xfe)
LSH(1, 0x7fff, 2, 0x1fffc)
LSH(2, 0x81, 16, 0x810000)
LSH(3, 0xff, 15, 0x7f8000)
LSH(4, 0x7fffffff, 0, 0x7fffffff)
#if __WORDSIZE == 32
LSH(5, 0xffffffff, 8, 0xffffff00)
LSH(6, 0x7fffffff, 3, 0xfffffff8)
LSH(7, -0x7f, 31, 0x80000000)
LSH(8, -0x7fff, 30, 0x40000000)
LSH(9, -0x7fffffff, 29, 0x20000000)
LSH(10, 0x80000001, 28, 0x10000000)
LSH(11, 0x8001, 17, 0x20000)
LSH(12, 0x80000001, 18, 0x40000)
LSH(13, -0xffff, 24, 0x1000000)
#else
LSH(5, 0xffffffff, 8, 0xffffffff00)
LSH(6, 0x7fffffff, 3, 0x3fffffff8)
LSH(7, -0x7f, 31, 0xffffffc080000000)
LSH(8, -0x7fff, 30, 0xffffe00040000000)
LSH(9, -0x7fffffff, 29, 0xf000000020000000)
LSH(10, 0x80000001, 28, 0x800000010000000)
LSH(11, 0x8001, 17, 0x100020000)
LSH(12, 0x80000001, 18, 0x2000000040000)
LSH(13, -0xffff, 24, 0xffffff0001000000)
LSH(14, 0x7f, 33, 0xfe00000000)
LSH(15, 0x7ffff, 34, 0x1ffffc00000000)
LSH(16, 0x7fffffff, 35, 0xfffffff800000000)
LSH(17, -0x7f, 63, 0x8000000000000000)
LSH(18, -0x7fff, 62, 0x4000000000000000)
LSH(19, -0x7fffffff, 61, 0x2000000000000000)
LSH(20, 0x80000001, 60, 0x1000000000000000)
LSH(21, 0x81, 48, 0x81000000000000)
LSH(22, 0x8001, 49, 0x2000000000000)
LSH(23, 0x80000001, 40, 0x10000000000)
LSH(24, 0xff, 47, 0x7f800000000000)
LSH(25, 0xffff0001, 56, 0x100000000000000)
LSH(26, 0xffffffff, 40, 0xffffff0000000000)
LSH(27, 0x7fffffffff, 33, 0xfffffffe00000000)
LSH(28, -0x7fffffffff, 63, 0x8000000000000000)
LSH(29, 0x8000000001, 48, 0x1000000000000)
LSH(30, 0xffffffffff, 47, 0xffff800000000000)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_mul.ok Normal file
View file

@ -0,0 +1 @@
ok

58
check/alu_mul.tst Normal file
View file

@ -0,0 +1,58 @@
#include "alu.inc"
.code
prolog
#define MUL(N, I0, I1, V) ALU(N, , mul, I0, I1, V)
MUL(0, 0x7fffffff, 1, 0x7fffffff)
MUL(1, 1, 0x7fffffff, 0x7fffffff)
MUL(2, 0x80000000, 1, 0x80000000)
MUL(3, 1, 0x80000000, 0x80000000)
MUL(4, 0x7fffffff, 2, 0xfffffffe)
MUL(5, 2, 0x7fffffff, 0xfffffffe)
MUL(6, 0x7fffffff, 0, 0)
MUL(7, 0, 0x7fffffff, 0)
#if __WORDSIZE == 32
MUL(8, 0x80000000, 2, 0)
MUL(9, 2, 0x80000000, 0)
MUL(10, 0x7fffffff, 0x80000000, 0x80000000)
MUL(11, 0x80000000, 0x7fffffff, 0x80000000)
MUL(12, 0x7fffffff, 0xffffffff, 0x80000001)
MUL(13, 0xffffffff, 0x7fffffff, 0x80000001)
MUL(14, 0xffffffff, 0xffffffff, 1)
#else
MUL(8, 0x80000000, 2, 0x100000000)
MUL(9, 2, 0x80000000, 0x100000000)
MUL(10, 0x7fffffff, 0x80000000, 0x3fffffff80000000)
MUL(11, 0x80000000, 0x7fffffff, 0x3fffffff80000000)
MUL(12, 0x7fffffff, 0xffffffff, 0x7ffffffe80000001)
MUL(13, 0xffffffff, 0x7fffffff, 0x7ffffffe80000001)
MUL(14, 0xffffffff, 0xffffffff, 0xfffffffe00000001)
MUL(15, 0x7fffffffffffffff, 1, 0x7fffffffffffffff)
MUL(16, 1, 0x7fffffffffffffff, 0x7fffffffffffffff)
MUL(17, 0x8000000000000000, 1, 0x8000000000000000)
MUL(18, 1, 0x8000000000000000, 0x8000000000000000)
MUL(19, 0x7fffffffffffffff, 2, 0xfffffffffffffffe)
MUL(20, 2, 0x7fffffffffffffff, 0xfffffffffffffffe)
MUL(21, 0x8000000000000000, 2, 0)
MUL(22, 2, 0x8000000000000000, 0)
MUL(23, 0x7fffffffffffffff, 0x8000000000000000, 0x8000000000000000)
MUL(24, 0x8000000000000000, 0x7fffffffffffffff, 0x8000000000000000)
MUL(25, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000001)
MUL(26, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000001)
MUL(27, 0xffffffffffffffff, 0xffffffffffffffff, 1)
#endif
#undef MUL
#define MUL(N, T, I0, I1, V) FOP(N, T, mul, I0, I1, V)
MUL(0, _f, -0.5, 0.5, -0.25)
MUL(1, _f, 0.25, 0.75, 0.1875)
MUL(0, _d, -0.5, 0.5, -0.25)
MUL(1, _d, 0.25, 0.75, 0.1875)
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_neg.ok Normal file
View file

@ -0,0 +1 @@
ok

41
check/alu_neg.tst Normal file
View file

@ -0,0 +1,41 @@
#include "alu.inc"
.code
prolog
#define NEG(N, I, V) UN(N, neg, I, V)
NEG(0, 0, 0)
#if __WORDSIZE == 32
NEG(1, 1, 0xffffffff)
NEG(2, 0xffffffff, 1)
NEG(3, 0x80000000, 0x80000000)
NEG(4, 0x7fffffff, 0x80000001)
NEG(5, 0x80000001, 0x7fffffff)
#else
NEG(1, 1, 0xffffffffffffffff)
NEG(2, 0xffffffff, 0xffffffff00000001)
NEG(3, 0x80000000, 0xffffffff80000000)
NEG(4, 0x7fffffff, 0xffffffff80000001)
NEG(5, 0x80000001, 0xffffffff7fffffff)
NEG(6, 0xffffffffffffffff, 1)
NEG(7, 0x8000000000000000, 0x8000000000000000)
NEG(8, 0x7fffffffffffffff, 0x8000000000000001)
#endif
#undef NEG
#define NEG(N, T, I, V) FUN(N, T, neg, I, V)
NEG(0, _f, 0.0, -0.0)
NEG(1, _f, 0.5, -0.5)
NEG(2, _f, $(1 / 0.0), $(-1.0 / 0))
NEG(3, _f, -1.25, 1.25)
NEG(0, _d, 0.0, -0.0)
NEG(1, _d, 0.5, -0.5)
NEG(2, _d, $(1.0 / 0), $(-1 / 0.0))
NEG(3, _d, -1.25, 1.25)
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_or.ok Normal file
View file

@ -0,0 +1 @@
ok

35
check/alu_or.tst Normal file
View file

@ -0,0 +1,35 @@
#include "alu.inc"
.code
prolog
#define OR(N, I0, I1, V) ALU(N, , or, I0, I1, V)
OR(0, 0x7fffffff, 1, 0x7fffffff)
OR(1, 1, 0x7fffffff, 0x7fffffff)
OR(2, 0x80000000, 1, 0x80000001)
OR(3, 1, 0x80000000, 0x80000001)
OR(4, 0x7fffffff, 0x80000000, 0xffffffff)
OR(5, 0x80000000, 0x7fffffff, 0xffffffff)
OR(6, 0x7fffffff, 0xffffffff, 0xffffffff)
OR(7, 0xffffffff, 0x7fffffff, 0xffffffff)
OR(8, 0xffffffff, 0xffffffff, 0xffffffff)
OR(9, 0x7fffffff, 0, 0x7fffffff)
OR(10, 0, 0x7fffffff, 0x7fffffff)
#if __WORDSIZE == 64
OR(11, 0x7fffffffffffffff, 1, 0x7fffffffffffffff)
OR(12, 1, 0x7fffffffffffffff, 0x7fffffffffffffff)
OR(13, 0x8000000000000000, 1, 0x8000000000000001)
OR(14, 1, 0x8000000000000000, 0x8000000000000001)
OR(15, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff)
OR(16, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff)
OR(17, 0x7fffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)
OR(18, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff)
OR(19, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_rem.ok Normal file
View file

@ -0,0 +1 @@
ok

75
check/alu_rem.tst Normal file
View file

@ -0,0 +1,75 @@
#include "alu.inc"
.code
prolog
#define REM(N, I0, I1, V) ALU(N, , rem, I0, I1, V)
#define UREM(N, I0, I1, V) ALU(N, _u, rem, I0, I1, V)
REM(0, 0x7fffffff, 1, 0)
REM(1, 1, 0x7fffffff, 1)
REM(2, 0x80000000, 1, 0)
REM(3, 1, 0x80000000, 1)
REM(4, 0x7fffffff, 2, 1)
REM(5, 2, 0x7fffffff, 2)
REM(6, 0x80000000, 2, 0)
REM(7, 2, 0x80000000, 2)
REM(8, 0x7fffffff, 0x80000000, 0x7fffffff)
REM(9, 0, 0x7fffffff, 0)
REM(10, 0xffffffff, 0xffffffff, 0)
UREM(0, 0x7fffffff, 1, 0)
UREM(1, 1, 0x7fffffff, 1)
UREM(2, 0x80000000, 1, 0)
UREM(3, 1, 0x80000000, 1)
UREM(4, 0x7fffffff, 2, 1)
UREM(5, 2, 0x7fffffff, 2)
UREM(6, 0x80000000, 2, 0)
UREM(7, 2, 0x80000000, 2)
UREM(8, 0x7fffffff, 0x80000000, 0x7fffffff)
UREM(9, 0x80000000, 0x7fffffff, 1)
UREM(10,0, 0x7fffffff, 0)
UREM(11,0x7fffffff, 0xffffffff, 0x7fffffff)
UREM(12,0xffffffff, 0x7fffffff, 1)
UREM(13,0xffffffff, 0xffffffff, 0)
#if __WORDSIZE == 32
REM(11, 0x80000000, 0x7fffffff, 0xffffffff)
REM(12, 0x7fffffff, 0xffffffff, 0)
REM(13, 0xffffffff, 0x7fffffff, 0xffffffff)
#else
REM(11, 0x80000000, 0x7fffffff, 1)
REM(12, 0x7fffffff, 0xffffffff, 0x7fffffff)
REM(13, 0xffffffff, 0x7fffffff, 1)
REM(14, 0x7fffffffffffffff, 1, 0)
REM(15, 1, 0x7fffffffffffffff, 1)
REM(16, 0x8000000000000000, 1, 0)
REM(17, 1, 0x8000000000000000, 1)
REM(18, 0x7fffffffffffffff, 2, 1)
REM(19, 2, 0x7fffffffffffffff, 2)
REM(20, 0x8000000000000000, 2, 0)
REM(21, 2, 0x8000000000000000, 2)
REM(22, 0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff)
REM(23, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff)
REM(24, 0x7fffffffffffffff, 0xffffffffffffffff, 0)
REM(25, 0xffffffffffffffff, 0x7fffffffffffffff, 0xffffffffffffffff)
REM(26, 0xffffffffffffffff, 0xffffffffffffffff, 0)
UREM(14,0x7fffffffffffffff, 1, 0)
UREM(15,1, 0x7fffffffffffffff, 1)
UREM(16,0x8000000000000000, 1, 0)
UREM(17,1, 0x8000000000000000, 1)
UREM(18,0x7fffffffffffffff, 2, 1)
UREM(19,2, 0x7fffffffffffffff, 2)
UREM(20,0x8000000000000000, 2, 0)
UREM(21,2, 0x8000000000000000, 2)
UREM(22,0x7fffffffffffffff, 0x8000000000000000, 0x7fffffffffffffff)
UREM(23,0x8000000000000000, 0x7fffffffffffffff, 1)
UREM(24,0x7fffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff)
UREM(25,0xffffffffffffffff, 0x7fffffffffffffff, 1)
UREM(26,0xffffffffffffffff, 0xffffffffffffffff, 0)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_rsh.ok Normal file
View file

@ -0,0 +1 @@
ok

84
check/alu_rsh.tst Normal file
View file

@ -0,0 +1,84 @@
#include "alu.inc"
.code
prolog
#define RSH(N, I0, I1, V) ALU(N, , rsh, I0, I1, V)
#define URSH(N, I0, I1, V) ALU(N, _u, rsh, I0, I1, V)
RSH(0, 0xfe, 1, 0x7f)
RSH(1, 0x1fffc, 2, 0x7fff)
RSH(2, 0x40000000, 30, 1)
RSH(3, 0x20000000, 29, 1)
RSH(4, 0x10000000, 28, 1)
RSH(5, 0x810000, 16, 0x81)
RSH(6, 0x20000, 17, 1)
RSH(7, 0x40000, 18, 1)
RSH(8, 0x7f8000, 15, 0xff)
RSH(9, 0x1000000, 24, 1)
RSH(10, 0x7fffffff, 0, 0x7fffffff)
URSH(0, 0xfe, 1, 0x7f)
URSH(1, 0x1fffc, 2, 0x7fff)
URSH(2, 0x80000000, 31, 1)
URSH(3, 0x40000000, 30, 1)
URSH(4, 0x20000000, 29, 1)
URSH(5, 0x10000000, 28, 1)
URSH(6, 0x810000, 16, 0x81)
URSH(7, 0x20000, 17, 1)
URSH(8, 0x40000, 18, 1)
URSH(9,0x7f8000, 15, 0xff)
URSH(10,0x1000000, 24, 1)
URSH(11,0xffffff00, 8, 0xffffff)
URSH(12,0x7fffffff, 0, 0x7fffffff)
#if __WORDSIZE == 32
RSH(11, 0xfffffff8, 3, 0xffffffff)
RSH(12, 0x80000000, 31, 0xffffffff)
RSH(13, 0xffffff00, 8, 0xffffffff)
URSH(13,0xfffffff8, 3, 0x1fffffff)
#else
RSH(11, 0x3fffffff8, 3, 0x7fffffff)
RSH(12, 0xffffffc080000000, 31, 0xffffffffffffff81)
RSH(13, 0xffffff00, 8, 0xffffff)
RSH(14, 0xfe00000000, 33, 0x7f)
RSH(15, 0x1ffffc00000000, 34, 0x7ffff)
RSH(16, 0xfffffff800000000, 29, 0xffffffffffffffc0)
RSH(17, 0x8000000000000000, 63, 0xffffffffffffffff)
RSH(18, 0x4000000000000000, 62, 1)
RSH(19, 0x2000000000000000, 61, 1)
RSH(20, 0x1000000000000000, 60, 1)
RSH(21, 0x81000000000000, 48, 0x81)
RSH(22, 0x2000000000000, 49, 1)
RSH(23, 0x10000000000, 40, 1)
RSH(24, 0x7f800000000000, 47, 0xff)
RSH(25, 0x100000000000000, 56, 1)
RSH(26, 0xffffff0000000000, 40, 0xffffffffffffffff)
RSH(27, 0xfffffffe00000000, 33, 0xffffffffffffffff)
RSH(28, 0x8000000000000001, 63, 0xffffffffffffffff)
RSH(29, 0x1000000000000, 48, 1)
RSH(30, 0xffff800000000000, 47, 0xffffffffffffffff)
URSH(13,0x3fffffff8, 3, 0x7fffffff)
URSH(14,0xffffffc080000000, 31, 0x1ffffff81)
URSH(15,0xfe00000000, 33, 0x7f)
URSH(16,0x1ffffc00000000, 34, 0x7ffff)
URSH(17,0xfffffff800000000, 29, 0x7ffffffc0)
URSH(18,0x8000000000000000, 63, 1)
URSH(19,0x4000000000000000, 62, 1)
URSH(20,0x2000000000000000, 61, 1)
URSH(21,0x1000000000000000, 60, 1)
URSH(22,0x81000000000000, 48, 0x81)
URSH(23,0x2000000000000, 49, 1)
URSH(24,0x10000000000, 40, 1)
URSH(25,0x7f800000000000, 47, 0xff)
URSH(26,0x100000000000000, 56, 1)
URSH(27,0xffffff0000000000, 40, 0xffffff)
URSH(28,0xfffffffe00000000, 33, 0x7fffffff)
URSH(29,0x8000000000000001, 63, 1)
URSH(30,0x1000000000000, 48, 1)
URSH(31,0xffff800000000000, 47, 0x1ffff)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_sub.ok Normal file
View file

@ -0,0 +1 @@
ok

48
check/alu_sub.tst Normal file
View file

@ -0,0 +1,48 @@
#include "alu.inc"
.code
prolog
#define SUB(N, I0, I1, V) ALU(N, , sub, I0, I1, V)
SUB(0, 0x7fffffff, 1, 0x7ffffffe)
SUB(2, 0x80000000, 1, 0x7fffffff)
SUB(3, 0x80000000, 0x7fffffff, 1)
SUB(4, 0xffffffff, 0xffffffff, 0)
SUB(5, 0xffffffff, 0x7fffffff, 0x80000000)
SUB(6, 0x7fffffff, 0, 0x7fffffff)
#if __WORDSIZE == 32
SUB(7, 1, 0x7fffffff, 0x80000002)
SUB(8, 1, 0x80000000, 0x80000001)
SUB(9, 0x7fffffff, 0x80000000, 0xffffffff)
SUB(10, 0x7fffffff, 0xffffffff, 0x80000000)
SUB(11, 0, 0x7fffffff, 0x80000001)
#else
SUB(7, 1, 0x7fffffff, 0xffffffff80000002)
SUB(8, 1, 0xffffffff80000000, 0x80000001)
SUB(9, 0x7fffffff, 0xffffffff80000000, 0xffffffff)
SUB(10, 0xffffffff7fffffff, 0xffffffffffffffff, 0xffffffff80000000)
SUB(11, 0, 0x7fffffff, 0xffffffff80000001)
SUB(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe)
SUB(13, 1, 0x7fffffffffffffff, 0x8000000000000002)
SUB(14, 0x8000000000000000, 1, 0x7fffffffffffffff)
SUB(15, 1, 0x8000000000000000, 0x8000000000000001)
SUB(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff)
SUB(17, 0x8000000000000000, 0x7fffffffffffffff, 1)
SUB(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000)
SUB(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000)
SUB(20, 0xffffffffffffffff, 0xffffffffffffffff, 0)
#endif
#undef SUB
#define SUB(N, T, I0, I1, V) FOP(N, T, sub, I0, I1, V)
SUB(0, _f, -0.5, 0.5, -1.0)
SUB(1, _f, 0.25, 0.75, -0.5)
SUB(0, _d, -0.5, 0.5, -1.0)
SUB(1, _d, 0.25, 0.75, -0.5)
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alu_xor.ok Normal file
View file

@ -0,0 +1 @@
ok

35
check/alu_xor.tst Normal file
View file

@ -0,0 +1,35 @@
#include "alu.inc"
.code
prolog
#define XOR(N, I0, I1, V) ALU(N, , xor, I0, I1, V)
XOR(0, 0x7fffffff, 1, 0x7ffffffe)
XOR(1, 1, 0x7fffffff, 0x7ffffffe)
XOR(2, 0x80000000, 1, 0x80000001)
XOR(3, 1, 0x80000000, 0x80000001)
XOR(4, 0x7fffffff, 0x80000000, 0xffffffff)
XOR(5, 0x80000000, 0x7fffffff, 0xffffffff)
XOR(6, 0x7fffffff, 0xffffffff, 0x80000000)
XOR(7, 0xffffffff, 0x7fffffff, 0x80000000)
XOR(9, 0xffffffff, 0xffffffff, 0)
XOR(10, 0x7fffffff, 0, 0x7fffffff)
XOR(11, 0, 0x7fffffff, 0x7fffffff)
#if __WORDSIZE == 64
XOR(12, 0x7fffffffffffffff, 1, 0x7ffffffffffffffe)
XOR(13, 1, 0x7fffffffffffffff, 0x7ffffffffffffffe)
XOR(14, 0x8000000000000000, 1, 0x8000000000000001)
XOR(15, 1, 0x8000000000000000, 0x8000000000000001)
XOR(16, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff)
XOR(17, 0x8000000000000000, 0x7fffffffffffffff, 0xffffffffffffffff)
XOR(18, 0x7fffffffffffffff, 0xffffffffffffffff, 0x8000000000000000)
XOR(19, 0xffffffffffffffff, 0x7fffffffffffffff, 0x8000000000000000)
XOR(20, 0xffffffffffffffff, 0xffffffffffffffff, 0)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alux_add.ok Normal file
View file

@ -0,0 +1 @@
ok

48
check/alux_add.tst Normal file
View file

@ -0,0 +1,48 @@
#include "alu.inc"
.code
prolog
#define ADDX(N, I0, I1, V) ALUX(N, add, I0, I1, V)
/* nothing */
ADDX(0, 0, 0, 0)
#if __WORDSIZE == 32
/* carry */
ADDX(1, 0xffffffff, 0xffffffff, 1)
/* overflow */
ADDX(2, 0x7fffffff, 1, 0)
/* overflow */
ADDX(3, 0x7fffffff, 0x7fffffff, 0)
/* carry */
ADDX(4, 0x7fffffff, 0x80000000, 0)
/* carry+overflow */
ADDX(5, 0x80000000, 0x80000000, 1)
#else
/* nothing */
ADDX(1, 0xffffffff, 0xffffffff, 0)
/* nothing */
ADDX(2, 0x7fffffff, 1, 0)
/* nothing */
ADDX(3, 0x7fffffff, 0x7fffffff, 0)
/* nothing */
ADDX(4, 0x7fffffff, 0x80000000, 0)
/* nothing */
ADDX(5, 0x80000000, 0x80000000, 0)
/* carry */
ADDX(6, 0xffffffffffffffff, 0xffffffffffffffff, 1)
/* overflow */
ADDX(7, 0x7fffffffffffffff, 1, 0)
/* overflow */
ADDX(8, 0x7fffffffffffffff, 0x7fffffffffffffff, 0)
/* overflow */
ADDX(9, 0x7fffffffffffffff, 0x8000000000000000, 0)
/* carry+overflow */
ADDX(10,0x8000000000000000, 0x8000000000000000, 1)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/alux_sub.ok Normal file
View file

@ -0,0 +1 @@
ok

48
check/alux_sub.tst Normal file
View file

@ -0,0 +1,48 @@
#include "alu.inc"
.code
prolog
#define SUBX(N, I0, I1, V) ALUX(N, sub, I0, I1, V)
/* nothing */
SUBX(0, 0, 0, 0)
#if __WORDSIZE == 32
/* carry */
SUBX(1, 0x7fffffff, 0xffffffff, 0xffffffff)
/* overflow */
SUBX(2, 0x80000000, 1, 0)
/* carry */
SUBX(3, 0x7fffffff, 0x80000000, 0xffffffff)
/* overflow */
SUBX(4, 0x80000000, 0x7fffffff, 0)
/* carry+overflow */
SUBX(5, 1, 0x80000000, 0xffffffff)
#else
/* carry */
SUBX(1, 0x7fffffff, 0xffffffff, -1)
/* nothing */
SUBX(2, 0x80000000, 1, 0)
/* carry */
SUBX(3, 0x7fffffff, 0x80000000, -1)
/* nothing */
SUBX(4, 0x80000000, 0x7fffffff, 0)
/* carry */
SUBX(5, 1, 0x80000000, -1)
/* carry */
SUBX(6, 0x7fffffffffffffff, 0xffffffffffffffff, -1)
/* overflow */
SUBX(7, 0x8000000000000000, 1, 0)
/* carry */
SUBX(8, 0x7fffffffffffffff, 0x8000000000000000, -1)
/* overflow */
SUBX(9, 0x8000000000000000, 0x7fffffffffffffff, 0)
/* carry+overflow */
SUBX(10,1, 0x8000000000000000, -1)
#endif
prepare 1
pushargi ok
finishi @printf
ret
epilog

1
check/branch.ok Normal file
View file

@ -0,0 +1 @@
ok

562
check/branch.tst Normal file
View file

@ -0,0 +1,562 @@
#if __WORDSIZE == 64
# define I7f 0x7fffffffffffffff
# define I80 0x8000000000000000
# define I81 0x8000000000000001
# define Iff 0xffffffffffffffff
#else
# define I7f 0x7fffffff
# define I80 0x80000000
# define I81 0x80000001
# define Iff 0xffffffff
#endif
.data 12
ok:
.c "ok\n"
. $($NaN = 0.0 / 0.0)
#define BOP(N, Ls, Rs, Lu, Ru, R0, R1) \
movi %R0 Ls \
movi %R1 Rs \
b##N##r N##r_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_##R0##_##R1: \
b##N##i N##i_##R0##_##R1 %R0 Rs \
calli @abort \
N##i_##R0##_##R1: \
movi %R0 Lu \
movi %R1 Ru \
b##N##r_u N##r_u_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_u_##R0##_##R1: \
b##N##i_u N##i_u_##R0##_##R1 %R0 Ru \
calli @abort \
N##i_u_##R0##_##R1: \
movi %R0 Ls \
movi %R1 Rs \
N##r %R0 %R0 %R1 \
beqi _##N##r_##R0##_##R1 %R0 1 \
calli @abort \
_##N##r_##R0##_##R1: \
movi %R0 Ls \
N##i %R1 %R0 Rs \
beqi _##N##i_##R0##_##R1 %R1 1 \
calli @abort \
_##N##i_##R0##_##R1: \
movi %R0 Lu \
movi %R1 Ru \
N##r_u %R0 %R0 %R1 \
beqi _##N##r_u_##R0##_##R1 %R0 1 \
calli @abort \
_##N##r_u_##R0##_##R1: \
movi %R0 Lu \
N##i_u %R1 %R0 Ru \
beqi _##N##i_u_##R0##_##R1 %R1 1 \
calli @abort \
_##N##i_u_##R0##_##R1:
#define EB(N, L, R, R0, R1) \
movi %R0 L \
movi %R1 R \
b##N##r N##r_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_##R0##_##R1: \
b##N##i N##i_##R0##_##R1 %R0 R \
calli @abort \
N##i_##R0##_##R1: \
movi %R0 L \
movi %R1 R \
N##r %R0 %R0 %R1 \
beqi _##N##r_##R0##_##R1 %R0 1 \
calli @abort \
_##N##r_##R0##_##R1: \
movi %R0 L \
N##i %R1 %R0 R \
beqi _##N##i_##R0##_##R1 %R1 1 \
calli @abort \
_##N##i_##R0##_##R1:
#define XEB(N, L, R, R0, R1) \
movi %R0 L \
movi %R1 R \
b##N##r N##r_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_##R0##_##R1: \
b##N##i N##i_##R0##_##R1 %R0 R \
calli @abort \
N##i_##R0##_##R1:
#define XBOP(N, Ls, Rs, Lu, Ru, R0, R1) \
movi %R0 Ls \
movi %R1 Rs \
b##N##r N##r_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_##R0##_##R1: \
movi %R0 Ls \
b##N##i N##i_##R0##_##R1 %R0 Rs \
calli @abort \
N##i_##R0##_##R1: \
movi %R0 Lu \
movi %R1 Ru \
b##N##r_u N##r_u_##R0##_##R1 %R0 %R1 \
calli @abort \
N##r_u_##R0##_##R1: \
movi %R0 Lu \
b##N##i_u N##i_u_##R0##_##R1 %R0 Ru \
calli @abort \
N##i_u_##R0##_##R1:
#define BOPI(N, Ls, Rs, Lu, Ru) \
BOP(N, Ls, Rs, Lu, Ru, v0, v1) \
BOP(N, Ls, Rs, Lu, Ru, v0, v2) \
BOP(N, Ls, Rs, Lu, Ru, v0, r0) \
BOP(N, Ls, Rs, Lu, Ru, v0, r1) \
BOP(N, Ls, Rs, Lu, Ru, v0, r2) \
BOP(N, Ls, Rs, Lu, Ru, v1, v0) \
BOP(N, Ls, Rs, Lu, Ru, v1, v2) \
BOP(N, Ls, Rs, Lu, Ru, v1, r0) \
BOP(N, Ls, Rs, Lu, Ru, v1, r1) \
BOP(N, Ls, Rs, Lu, Ru, v1, r2) \
BOP(N, Ls, Rs, Lu, Ru, v2, v0) \
BOP(N, Ls, Rs, Lu, Ru, v2, v1) \
BOP(N, Ls, Rs, Lu, Ru, v2, r0) \
BOP(N, Ls, Rs, Lu, Ru, v2, r1) \
BOP(N, Ls, Rs, Lu, Ru, v2, r2) \
BOP(N, Ls, Rs, Lu, Ru, r0, v0) \
BOP(N, Ls, Rs, Lu, Ru, r0, v1) \
BOP(N, Ls, Rs, Lu, Ru, r0, v2) \
BOP(N, Ls, Rs, Lu, Ru, r0, r1) \
BOP(N, Ls, Rs, Lu, Ru, r0, r2) \
BOP(N, Ls, Rs, Lu, Ru, r1, v0) \
BOP(N, Ls, Rs, Lu, Ru, r1, v1) \
BOP(N, Ls, Rs, Lu, Ru, r1, v2) \
BOP(N, Ls, Rs, Lu, Ru, r1, r0) \
BOP(N, Ls, Rs, Lu, Ru, r1, r2) \
BOP(N, Ls, Rs, Lu, Ru, r2, v0) \
BOP(N, Ls, Rs, Lu, Ru, r2, v1) \
BOP(N, Ls, Rs, Lu, Ru, r2, v2) \
BOP(N, Ls, Rs, Lu, Ru, r2, r0) \
BOP(N, Ls, Rs, Lu, Ru, r2, r1)
#define EBI(N, L, R) \
EB(N, L, R, v0, v1) \
EB(N, L, R, v0, v2) \
EB(N, L, R, v0, r0) \
EB(N, L, R, v0, r1) \
EB(N, L, R, v0, r2) \
EB(N, L, R, v1, v0) \
EB(N, L, R, v1, v2) \
EB(N, L, R, v1, r0) \
EB(N, L, R, v1, r1) \
EB(N, L, R, v1, r2) \
EB(N, L, R, v2, v0) \
EB(N, L, R, v2, v1) \
EB(N, L, R, v2, r0) \
EB(N, L, R, v2, r1) \
EB(N, L, R, v2, r2) \
EB(N, L, R, r0, v0) \
EB(N, L, R, r0, v1) \
EB(N, L, R, r0, v2) \
EB(N, L, R, r0, r1) \
EB(N, L, R, r0, r2) \
EB(N, L, R, r1, v0) \
EB(N, L, R, r1, v1) \
EB(N, L, R, r1, v2) \
EB(N, L, R, r1, r0) \
EB(N, L, R, r1, r2) \
EB(N, L, R, r2, v0) \
EB(N, L, R, r2, v1) \
EB(N, L, R, r2, v2) \
EB(N, L, R, r2, r0) \
EB(N, L, R, r2, r1)
#define XEBI(N, L, R) \
XEB(N, L, R, v0, v1) \
XEB(N, L, R, v0, v2) \
XEB(N, L, R, v0, r0) \
XEB(N, L, R, v0, r1) \
XEB(N, L, R, v0, r2) \
XEB(N, L, R, v1, v0) \
XEB(N, L, R, v1, v2) \
XEB(N, L, R, v1, r0) \
XEB(N, L, R, v1, r1) \
XEB(N, L, R, v1, r2) \
XEB(N, L, R, v2, v0) \
XEB(N, L, R, v2, v1) \
XEB(N, L, R, v2, r0) \
XEB(N, L, R, v2, r1) \
XEB(N, L, R, v2, r2) \
XEB(N, L, R, r0, v0) \
XEB(N, L, R, r0, v1) \
XEB(N, L, R, r0, v2) \
XEB(N, L, R, r0, r1) \
XEB(N, L, R, r0, r2) \
XEB(N, L, R, r1, v0) \
XEB(N, L, R, r1, v1) \
XEB(N, L, R, r1, v2) \
XEB(N, L, R, r1, r0) \
XEB(N, L, R, r1, r2) \
XEB(N, L, R, r2, v0) \
XEB(N, L, R, r2, v1) \
XEB(N, L, R, r2, v2) \
XEB(N, L, R, r2, r0) \
XEB(N, L, R, r2, r1)
#define XBOPI(N, Ls, Rs, Lu, Ru) \
XBOP(N, Ls, Rs, Lu, Ru, v0, v1) \
XBOP(N, Ls, Rs, Lu, Ru, v0, v2) \
XBOP(N, Ls, Rs, Lu, Ru, v0, r0) \
XBOP(N, Ls, Rs, Lu, Ru, v0, r1) \
XBOP(N, Ls, Rs, Lu, Ru, v0, r2) \
XBOP(N, Ls, Rs, Lu, Ru, v1, v0) \
XBOP(N, Ls, Rs, Lu, Ru, v1, v2) \
XBOP(N, Ls, Rs, Lu, Ru, v1, r0) \
XBOP(N, Ls, Rs, Lu, Ru, v1, r1) \
XBOP(N, Ls, Rs, Lu, Ru, v1, r2) \
XBOP(N, Ls, Rs, Lu, Ru, v2, v0) \
XBOP(N, Ls, Rs, Lu, Ru, v2, v1) \
XBOP(N, Ls, Rs, Lu, Ru, v2, r0) \
XBOP(N, Ls, Rs, Lu, Ru, v2, r1) \
XBOP(N, Ls, Rs, Lu, Ru, v2, r2) \
XBOP(N, Ls, Rs, Lu, Ru, r0, v0) \
XBOP(N, Ls, Rs, Lu, Ru, r0, v1) \
XBOP(N, Ls, Rs, Lu, Ru, r0, v2) \
XBOP(N, Ls, Rs, Lu, Ru, r0, r1) \
XBOP(N, Ls, Rs, Lu, Ru, r0, r2) \
XBOP(N, Ls, Rs, Lu, Ru, r1, v0) \
XBOP(N, Ls, Rs, Lu, Ru, r1, v1) \
XBOP(N, Ls, Rs, Lu, Ru, r1, v2) \
XBOP(N, Ls, Rs, Lu, Ru, r1, r0) \
XBOP(N, Ls, Rs, Lu, Ru, r1, r2) \
XBOP(N, Ls, Rs, Lu, Ru, r2, v0) \
XBOP(N, Ls, Rs, Lu, Ru, r2, v1) \
XBOP(N, Ls, Rs, Lu, Ru, r2, v2) \
XBOP(N, Ls, Rs, Lu, Ru, r2, r0) \
XBOP(N, Ls, Rs, Lu, Ru, r2, r1)
#define TBOPF(N, T, L, R) \
movi_##T %f0 L \
movi_##T %f1 R \
b##N##r##_##T N##r_##T %f0 %f1 \
calli @abort \
N##r_##T: \
b##N##i##_##T N##i_##T %f0 R \
calli @abort \
N##i_##T: \
movi_##T %f1 $NaN \
b##N##r##_##T N##r_##T##_##u %f0 %f1 \
jmpi N##r_##T##_##u0 \
N##r_##T##_##u: \
calli @abort \
N##r##_##T##_##u0: \
b##N##i##_##T N##i_##T##_##u %f0 $NaN \
jmpi N##i_##T##_##u0 \
N##i##_##T##_##u: \
calli @abort \
N##i##_##T##_##u0:
#define BOPF(N, L, R) \
TBOPF(N, f, L, R) \
TBOPF(N, d, L, R)
#define TUBOPF(N, T, L, R) \
movi_##T %f0 L \
movi_##T %f1 R \
b##N##r##_##T N##r_##T %f0 %f1 \
calli @abort \
N##r_##T: \
b##N##i##_##T N##i_##T %f0 R \
calli @abort \
N##i_##T: \
movi_##T %f1 $NaN \
b##N##r##_##T N##r_##T##_##u %f0 %f1 \
calli @abort \
N##r_##T##_##u: \
b##N##i##_##T N##i_##T##_##u %f0 $NaN \
calli @abort \
N##i##_##T##_##u:
#define UBOPF(N, L, R) \
TUBOPF(N, f, L, R) \
TUBOPF(N, d, L, R)
.code
prolog
movi %r0 -1
movi %r1 1
bltr xltr_r0_r1 %r0 %r1
calli @abort
xltr_r0_r1:
blti xlti_r0_r1 %r0 1
calli @abort
xlti_r0_r1:
movi %r0 1
movi %r1 -1
bltr_u xltru_r0_r1 %r0 %r1
calli @abort
xltru_r0_r1:
blti_u xltiu_r0_r1 %r0 -1
calli @abort
xltiu_r0_r1:
movi %r0 -1
movi %r1 -1
bler xler_r0_r1 %r0 %r1
calli @abort
xler_r0_r1:
blti xlei_r0_r1 %r0 1
calli @abort
xlei_r0_r1:
movi %r0 1
movi %r1 -1
bltr_u xlteu_r0_r1 %r0 %r1
calli @abort
xlteu_r0_r1:
blei_u xleiu_r0_r1 %r0 -1
calli @abort
xleiu_r0_r1:
movi %r0 32
movi %r1 32
beqr xeqr_r0_r1 %r0 %r1
calli @abort
xeqr_r0_r1:
beqi xeqi_r0_r1 %r0 32
calli @abort
xeqi_r0_r1:
movi %r0 -2
movi %r1 -2
bger xger_r0_r1 %r0 %r1
calli @abort
xger_r0_r1:
bgei xgei_r0_r1 %r0 -2
calli @abort
xgei_r0_r1:
movi %r0 2
movi %r1 2
bger_u xgeru_r0_r1 %r0 %r1
calli @abort
xgeru_r0_r1:
bgei_u xgeiu_r0_r1 %r0 2
calli @abort
xgeiu_r0_r1:
movi %r0 2
movi %r1 -2
bgtr xgtr_r0_r1 %r0 %r1
calli @abort
xgtr_r0_r1:
bgti xgti_r0_r1 %r0 -2
calli @abort
xgti_r0_r1:
movi %r0 -2
movi %r1 2
bgtr_u xgtru_r0_r1 %r0 %r1
calli @abort
xgtru_r0_r1:
bgti_u xgtiu_r0_r1 %r0 2
calli @abort
xgtiu_r0_r1:
movi %r0 -3
movi %r1 3
bner xner_r0_r1 %r0 %r1
calli @abort
xner_r0_r1:
bnei xnei_r0_r1 %r0 3
calli @abort
xnei_r0_r1:
movi %r0 1
movi %r1 3
bmsr xmsr_r0_r1 %r0 %r1
calli @abort
xmsr_r0_r1:
bmsi xmsi_r0_r1 %r0 3
calli @abort
xmsi_r0_r1:
movi %r0 1
movi %r1 2
bmcr xmcr_r0_r1 %r0 %r1
calli @abort
xmcr_r0_r1:
bmci xmci_r0_r1 %r0 2
calli @abort
xmci_r0_r1:
movi %r0 I7f
movi %r1 1
boaddr xoaddr_r0_r1 %r0 %r1
calli @abort
xoaddr_r0_r1:
movi %r0 Iff
movi %r1 1
boaddr_u xoaddr_u_r0_r1 %r0 %r1
calli @abort
xoaddr_u_r0_r1:
movi %r0 I7f
boaddi xoaddi_r0_r1 %r0 1
calli @abort
xoaddi_r0_r1:
movi %r0 Iff
boaddi_u xoaddi_u_r0_r1 %r0 1
calli @abort
xoaddi_u_r0_r1:
movi %r0 I80
movi %r1 1
bxaddr xxaddr_r0_r1 %r0 %r1
calli @abort
xxaddr_r0_r1:
movi %r0 I80
bxaddi xxaddi_r0_r1 %r0 1
calli @abort
xxaddi_r0_r1:
movi %r0 I7f
movi %r1 1
bxaddr_u xxaddr_u_r0_r1 %r0 %r1
calli @abort
xxaddr_u_r0_r1:
movi %r0 I7f
bxaddi_u xxaddi_u_r0_r1 %r0 1
calli @abort
xxaddi_u_r0_r1:
movi %r0 I80
movi %r1 1
bosubr xosubr_r0_r1 %r0 %r1
calli @abort
xosubr_r0_r1:
movi %r0 0
movi %r1 1
bosubr_u xosubr_u_r0_r1 %r0 %r1
calli @abort
xosubr_u_r0_r1:
movi %r0 I80
bosubi xosubi_r0_r1 %r0 1
calli @abort
xosubi_r0_r1:
movi %r0 0
bosubi_u xosubi_u_r0_r1 %r0 1
calli @abort
xosubi_u_r0_r1:
movi %r0 I81
movi %r1 1
bxsubr xxsubr_r0_r1 %r0 %r1
calli @abort
xxsubr_r0_r1:
movi %r0 I81
bxsubi xxsubi_r0_r1 %r0 1
calli @abort
xxsubi_r0_r1:
movi %r0 I80
movi %r1 1
bxsubr_u xxsubr_u_r0_r1 %r0 %r1
calli @abort
xxsubr_u_r0_r1:
movi %r0 I80
bxsubi_u xxsubi_u_r0_r1 %r0 1
calli @abort
xxsubi_u_r0_r1:
movi_f %f0 1
movi_f %f1 2
bltr_f xltr_f_f0_f1 %f0 %f1
calli @abort
xltr_f_f0_f1:
blti_f xlti_f_f0_f1 %f0 2
calli @abort
xlti_f_f0_f1:
movi_f %f0 -1
movi_f %f1 -1
bler_f xler_f_f0_f1 %f0 %f1
calli @abort
xler_f_f0_f1:
blei_f xlei_f_f0_f1 %f0 -1
calli @abort
xlei_f_f0_f1:
movi_f %f0 -2
movi_f %f1 -2
beqr_f xeqr_f_f0_f1 %f0 %f1
calli @abort
xeqr_f_f0_f1:
beqi_f xeqi_f_f0_f1 %f0 -2
calli @abort
xeqi_f_f0_f1:
movi_f %f0 -3
movi_f %f1 -3
bger_f xger_f_f0_f1 %f0 %f1
calli @abort
xger_f_f0_f1:
bgei_f xgei_f_f0_f1 %f0 -3
calli @abort
xgei_f_f0_f1:
movi_f %f0 2
movi_f %f1 1
bgtr_f xgtr_f_f0_f1 %f0 %f1
calli @abort
xgtr_f_f0_f1:
bgti_f xgti_f_f0_f1 %f0 1
calli @abort
xgti_f_f0_f1:
movi_f %f0 0
movi_f %f1 2
bner_f xner_f_f0_f1 %f0 %f1
calli @abort
xner_f_f0_f1:
bnei_f xnei_f_f0_f1 %f0 2
calli @abort
xnei_f_f0_f1:
BOPI(lt, -1, 1, 1, -1)
BOPI(le, -1, -1, 1, 1)
EBI(eq, 32, 32)
BOPI(ge, -2, -2, 2, 2)
BOPI(gt, 2, -2, -2, 2)
EBI(ne, 3, -3)
XEBI(ms, 1, 3)
XEBI(mc, 1, 2)
XBOPI(oadd, I7f, 1, Iff, 1)
XBOPI(xadd, I80, 1, I7f, 1)
XBOPI(osub, I80, 1, 0, 1)
XBOPI(xsub, I81, 1, I80, 1)
BOPF(lt, 1, 2)
BOPF(le, 2, 2)
BOPF(eq, 3, 3)
BOPF(ge, 3, 3)
BOPF(gt, 4, 3)
BOPF(ne, 4, 3)
UBOPF(unlt, 1, 2)
UBOPF(unle, 2, 2)
UBOPF(uneq, 3, 3)
UBOPF(unge, 3, 3)
UBOPF(ungt, 4, 3)
BOPF(ltgt, 4, 3)
movi_f %f0 5
movi_f %f1 5
bordr_f ordr_f %f0 %f1
calli @abort
ordr_f:
bordi_f ordi_f %f0 1
calli @abort
ordi_f:
bordi_f ordi_f_u %f0 $NaN
jmpi ordi_f_u0
ordi_f_u:
calli @abort
ordi_f_u0:
movi_f %f0 5
movi_f %f1 5
bunordr_f unordr_f %f0 %f1
jmpi unordr_f_0
unordr_f:
calli @abort
unordr_f_0:
bunordi_f unordi_f %f0 1
jmpi unordi_f_0
unordi_f:
calli @abort
unordi_f_0:
bunordi_f unordi_f_1 %f0 $NaN
calli @abort
unordi_f_1:
// just to know did not crash or abort
prepare 1
pushargi ok
finishi @printf
ret
epilog

View file

@ -44,9 +44,15 @@
#define jit_size(vector) (sizeof(vector) / sizeof((vector)[0]))
#define jit_reg_free_p(regno) \
(!jit_regset_tstbit(_jit->reglive, regno) && \
!jit_regset_tstbit(_jit->regarg, regno) && \
!jit_regset_tstbit(_jit->regsav, regno))
/*
* Private jit_class bitmasks
*/
#define jit_class_named 0x00400000 /* hit must be the named reg */
#define jit_class_nospill 0x00800000 /* hint to fail if need spill */
#define jit_class_sft 0x01000000 /* not a hardware register */
#define jit_class_rg8 0x04000000 /* x86 8 bits */

View file

@ -409,7 +409,7 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CC_MVN(cc,rd,rm) corrr(cc,ARM_MVN,0,rd,rm)
# define MVN(rd,rm) CC_MVN(ARM_CC_AL,rd,rm)
# define T1_MVN(rd,rm) is(THUMB_MVN|(_u3(rm)<<3)|_u3(rd))
# define T2_MVN(rd,rm) torrr(THUMB2_MVN,rd,_R15_REGNO,rm)
# define T2_MVN(rd,rm) torrr(THUMB2_MVN,_R15_REGNO,rd,rm)
# define CC_MVNI(cc,rd,im) corri(cc,ARM_MVN|ARM_I,0,rd,im)
# define MVNI(rd,im) CC_MVNI(ARM_CC_AL,rd,im)
# define T2_MVNI(rd,im) torri(THUMB2_MVNI,_R15_REGNO,rd,im)
@ -816,10 +816,10 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define T2_POP(im) tpp(THUMB2_POP,im)
# define jit_get_reg_args() \
do { \
(void)jit_get_reg(_R0|jit_class_gpr); \
(void)jit_get_reg(_R1|jit_class_gpr); \
(void)jit_get_reg(_R2|jit_class_gpr); \
(void)jit_get_reg(_R3|jit_class_gpr); \
(void)jit_get_reg(_R0|jit_class_named|jit_class_gpr); \
(void)jit_get_reg(_R1|jit_class_named|jit_class_gpr); \
(void)jit_get_reg(_R2|jit_class_named|jit_class_gpr); \
(void)jit_get_reg(_R3|jit_class_named|jit_class_gpr); \
} while (0)
# define jit_unget_reg_args() \
do { \

View file

@ -156,8 +156,8 @@ static void _swf_negr_d(jit_state_t*,jit_int32_t,jit_int32_t);
# define swf_muli_d(r0,r1,i0) swf_ddd_(__aeabi_dmul,r0,r1,i0)
# define swf_divr_f(r0,r1,r2) swf_fff(__aeabi_fdiv,r0,r1,r2)
# define swf_divi_f(r0,r1,i0) swf_fff_(__aeabi_fdiv,r0,r1,i0)
# define swf_divr_d(r0,r1,r2) swf_ddd(__aeabi_dsub,r0,r1,r2)
# define swf_divi_d(r0,r1,i0) swf_ddd_(__aeabi_dsub,r0,r1,i0)
# define swf_divr_d(r0,r1,r2) swf_ddd(__aeabi_ddiv,r0,r1,r2)
# define swf_divi_d(r0,r1,i0) swf_ddd_(__aeabi_ddiv,r0,r1,i0)
# define swf_ltr_f(r0,r1,r2) swf_iff(__aeabi_fcmplt,r0,r1,r2)
# define swf_lti_f(r0,r1,i0) swf_iff_(__aeabi_fcmplt,r0,r1,i0)
# define swf_ltr_d(r0,r1,r2) swf_idd(__aeabi_dcmplt,r0,r1,r2)

View file

@ -37,10 +37,6 @@
#define jit_exchange_p() 1
/* FIXME is it really required to not touch _R10? */
#define jit_reg_free_p(regno) \
(!jit_regset_tstbit(_jit->reglive, regno) && \
!jit_regset_tstbit(_jit->regarg, regno) && \
!jit_regset_tstbit(_jit->regsav, regno))
/*
* Types
@ -290,28 +286,28 @@ _jit_reti(jit_state_t *_jit, jit_word_t u)
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
jit_movr_f(JIT_RET, u);
jit_movr_f(JIT_FRET, u);
jit_ret();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
jit_movi_f(JIT_RET, u);
jit_movi_f(JIT_FRET, u);
jit_ret();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
jit_movr_d(JIT_RET, u);
jit_movr_d(JIT_FRET, u);
jit_ret();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
jit_movi_d(JIT_RET, u);
jit_movi_d(JIT_FRET, u);
jit_ret();
}

View file

@ -40,7 +40,7 @@
# define stxi(u, v, w) stxi_l(u, v, w)
# define can_sign_extend_int_p(im) \
(((im) >= 0 && (long)(im) <= 0x7fffffffL) || \
((im) < 0 && (long)(im) >= -0x80000000L))
((im) < 0 && (long)(im) > -0x80000000L))
# define can_zero_extend_int_p(im) \
((im) >= 0 && (im) < 0x80000000L)
# define fits_uint32_p(im) ((im & 0xffffffff00000000L) == 0)
@ -975,8 +975,8 @@ _subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
lea(-i0, r1, _NOREG, _SCL1, r0);
}
else if (r0 != r1) {
movi(r0, i0);
isubr(r0, r1);
movi(r0, -i0);
iaddr(r0, r1);
}
else {
reg = jit_get_reg(jit_class_gpr);
@ -1064,7 +1064,7 @@ _imuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
rex(0, 1, r1, _NOREG, r0);
rex(0, 1, r0, _NOREG, r1);
if ((jit_int8_t)i0 == i0) {
ic(0x6b);
mrm(0x03, r7(r0), r7(r1));
@ -1147,16 +1147,25 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
{
jit_int32_t div;
jit_int32_t reg;
jit_int32_t set;
jit_int32_t use;
if (r0 != _RDX_REGNO)
(void)jit_get_reg(_RDX|jit_class_gpr);
if (r0 != _RAX_REGNO)
(void)jit_get_reg(_RAX|jit_class_gpr);
set = use = 0;
if (r0 != _RDX_REGNO && r1 != _RDX_REGNO && r2 != _RDX_REGNO)
set |= 1 << _RDX_REGNO;
if (r0 != _RAX_REGNO && r1 != _RAX_REGNO && r2 != _RAX_REGNO)
set |= 1 << _RAX_REGNO;
if (set & (1 <<_RDX_REGNO))
(void)jit_get_reg(_RDX|jit_class_gpr|jit_class_named);
if (set & (1 << _RAX_REGNO))
(void)jit_get_reg(_RAX|jit_class_gpr|jit_class_named);
if (r2 == _RAX_REGNO) {
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
reg = jit_get_reg(r1 == _RCX_REGNO ? _RBX : _RCX);
reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
jit_class_gpr|jit_class_named);
use = 1;
div = rn(reg);
movr(div, _RAX_REGNO);
if (r1 != _RAX_REGNO)
@ -1172,13 +1181,14 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
movr(_RAX_REGNO, r1);
}
div = r0;
reg = 0;
}
}
else if (r2 == _RDX_REGNO) {
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
reg = jit_get_reg(r1 == _RCX_REGNO ? _RBX : _RCX);
reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
jit_class_gpr|jit_class_named);
use = 1;
div = rn(reg);
movr(div, _RDX_REGNO);
if (r1 != _RAX_REGNO)
@ -1189,14 +1199,12 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
movr(_RAX_REGNO, r1);
movr(r0, _RDX_REGNO);
div = r0;
reg = 0;
}
}
else {
if (r1 != _RAX_REGNO)
movr(_RAX_REGNO, r1);
div = r2;
reg = 0;
}
if (sign) {
@ -1208,19 +1216,21 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
idivr_u(div);
}
if (reg)
if (use)
jit_unget_reg(reg);
if (r0 != _RAX_REGNO) {
if (divide)
movr(r0, _RAX_REGNO);
jit_unget_reg(_RAX);
}
if (r0 != _RDX_REGNO) {
if (!divide)
movr(r0, _RDX_REGNO);
jit_unget_reg(_RDX);
}
if (set & (1 <<_RDX_REGNO))
jit_unget_reg(_RDX);
if (set & (1 << _RAX_REGNO))
jit_unget_reg(_RAX);
}
static void
@ -1229,6 +1239,8 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
{
jit_int32_t reg;
jit_int32_t div;
jit_int32_t set;
jit_int32_t use;
if (divide) {
switch (i0) {
@ -1275,23 +1287,28 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
return;
}
if (r0 != _RDX_REGNO)
(void)jit_get_reg(_RDX|jit_class_gpr);
if (r0 != _RAX_REGNO)
(void)jit_get_reg(_RAX|jit_class_gpr);
set = use = 0;
if (r0 != _RDX_REGNO && r1 != _RDX_REGNO)
set |= 1 << _RDX_REGNO;
if (r0 != _RAX_REGNO && r1 != _RAX_REGNO)
set |= 1 << _RAX_REGNO;
if (set & (1 <<_RDX_REGNO))
(void)jit_get_reg(_RDX|jit_class_gpr|jit_class_named);
if (set & (1 << _RAX_REGNO))
(void)jit_get_reg(_RAX|jit_class_gpr|jit_class_named);
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO || r0 == r1) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
reg = jit_get_reg(_RCX);
reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
jit_class_gpr|jit_class_named);
use = 1;
div = rn(reg);
}
else {
reg = 0;
else
div = r0;
}
movi(div, i0);
movr(_RAX, r1);
movr(_RAX_REGNO, r1);
if (sign) {
sign_extend_rdx_rax();
@ -1302,19 +1319,21 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
idivr_u(div);
}
if (reg)
if (use)
jit_unget_reg(reg);
if (r0 != _RAX_REGNO) {
if (divide)
movr(r0, _RAX_REGNO);
jit_unget_reg(_RAX);
}
if (r0 != _RDX_REGNO) {
if (!divide)
movr(r0, _RDX_REGNO);
jit_unget_reg(_RDX);
}
if (set & (1 <<_RDX_REGNO))
jit_unget_reg(_RDX);
if (set & (1 << _RAX_REGNO))
jit_unget_reg(_RAX);
}
static void
@ -1386,7 +1405,7 @@ _ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
}
else if (r0 != r1) {
movi(r0, i0);
ixorr(r0, r1);
iorr(r0, r1);
}
else {
reg = jit_get_reg(jit_class_gpr);
@ -1448,6 +1467,7 @@ _rotshr(jit_state_t *_jit, jit_int32_t code,
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t reg;
jit_int32_t use;
if (r0 == _RCX_REGNO) {
reg = jit_get_reg(jit_class_gpr);
@ -1459,13 +1479,30 @@ _rotshr(jit_state_t *_jit, jit_int32_t code,
jit_unget_reg(reg);
}
else if (r2 != _RCX_REGNO) {
reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), _RCX_REGNO);
movr(_RCX_REGNO, r2);
movr(r0, r1);
use = !jit_reg_free_p(_RCX);
if (use) {
reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), _RCX_REGNO);
}
else
reg = 0;
if (r1 == _RCX_REGNO) {
if (r0 == r2)
xchgr(r0, _RCX_REGNO);
else {
movr(r0, r1);
movr(_RCX_REGNO, r2);
}
}
else {
movr(_RCX_REGNO, r2);
movr(r0, r1);
}
irotshr(code, r0);
movr(_RCX_REGNO, rn(reg));
jit_unget_reg(reg);
if (use) {
movr(_RCX_REGNO, rn(reg));
jit_unget_reg(reg);
}
}
else {
movr(r0, r1);

View file

@ -148,17 +148,18 @@ _jit_get_reg(jit_state_t *_jit, jit_int32_t regspec)
jit_int32_t spec;
jit_int32_t regno;
/* if asking for an explicit register value, assume it will
* properly handle the case of the register also being an
* argument for the instruction, or the register value
* being live */
spec = regspec & ~(jit_class_chk|jit_class_nospill);
if ((regno = jit_regno(spec))) {
if (spec & jit_class_named) {
regno = jit_regno(spec);
if (jit_regset_tstbit(_jit->regsav, regno))
/* fail if register is spilled */
goto fail;
if (jit_regset_tstbit(_jit->regarg, regno)) {
if (jit_regset_tstbit(_jit->regarg, regno))
/* fail if register is an argument to current instruction */
goto fail;
if (jit_regset_tstbit(_jit->reglive, regno)) {
if (regspec & jit_class_nospill)
/* fail if register is live and should not spill/reload */
goto fail;
goto spill;
}
@ -1453,6 +1454,12 @@ _thread_jumps(jit_state_t *_jit)
case jit_code_callr: case jit_code_calli:
/* non optimizable jump like code */
break;
case jit_code_beqr_f: case jit_code_beqi_f:
case jit_code_beqr_d: case jit_code_beqi_d:
case jit_code_bltgtr_f: case jit_code_bltgti_f:
case jit_code_bltgtr_d: case jit_code_bltgti_d:
/* non optimizable jump code */
break;
default:
mask = jit_classify(node->code);
if (mask & jit_cc_a0_jmp) {
@ -1633,8 +1640,10 @@ reverse_jump_code(jit_code_t code)
case jit_code_blti_f: return (jit_code_bungei_f);
case jit_code_bler_f: return (jit_code_bungtr_f);
case jit_code_blei_f: return (jit_code_bungti_f);
#if 0
case jit_code_beqr_f: return (jit_code_bltgtr_f);
case jit_code_beqi_f: return (jit_code_bltgti_f);
#endif
case jit_code_bger_f: return (jit_code_bunltr_f);
case jit_code_bgei_f: return (jit_code_bunlti_f);
case jit_code_bgtr_f: return (jit_code_bunler_f);
@ -1651,8 +1660,10 @@ reverse_jump_code(jit_code_t code)
case jit_code_bungei_f: return (jit_code_blti_f);
case jit_code_bungtr_f: return (jit_code_bler_f);
case jit_code_bungti_f: return (jit_code_blei_f);
#if 0
case jit_code_bltgtr_f: return (jit_code_beqr_f);
case jit_code_bltgti_f: return (jit_code_beqi_f);
#endif
case jit_code_bordr_f: return (jit_code_bunordr_f);
case jit_code_bordi_f: return (jit_code_bunordi_f);
case jit_code_bunordr_f:return (jit_code_bordr_f);