From c26ae55ef1def0e28517562c810d5285927ef108 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 24 Sep 2001 12:56:27 +0000 Subject: [PATCH] * mono/jit/x86.brg: impl. more opcodes svn path=/trunk/mono/; revision=941 --- ChangeLog | 2 + mono/jit/jit.c | 16 +++++ mono/jit/testjit.c | 16 +++++ mono/jit/x86.brg | 130 +++++++++++++++++++++++++++++++++++++++- mono/tests/Makefile.am | 22 ++++++- mono/tests/jit-float.cs | 75 +++++++++++++++++++++++ mono/tests/jit-int.cs | 7 +++ mono/tests/jit-long.cs | 9 +++ mono/tests/jit-uint.cs | 4 ++ mono/tests/jit-ulong.cs | 4 ++ 10 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 mono/tests/jit-float.cs diff --git a/ChangeLog b/ChangeLog index 345339985d2..969eca3bf25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2001-09-24 Dietmar Maurer + * mono/tests/Makefile.am (testjit): a new target to test the JITer + * mono/tests/jit-*: added some test for the JITer 2001-09-23 Dick Porter diff --git a/mono/jit/jit.c b/mono/jit/jit.c index 3d41ee8a425..fbeba1761e2 100644 --- a/mono/jit/jit.c +++ b/mono/jit/jit.c @@ -767,6 +767,22 @@ mono_compile_method (MonoMethod *method) MAKE_BI_ALU (REM) MAKE_BI_ALU (REM_UN) + case CEE_NEG: { + ip++; + sp--; + t1 = ctree_new (mp, MB_TERM_NEG, 0, sp [0], NULL); + t1->cli_addr = sp [0]->cli_addr; + PUSH_TREE (t1); + break; + } + case CEE_NOT: { + ip++; + sp--; + t1 = ctree_new (mp, MB_TERM_NOT, 0, sp [0], NULL); + t1->cli_addr = sp [0]->cli_addr; + PUSH_TREE (t1); + break; + } case CEE_BR_S: { ++ip; t1 = ctree_new_leaf (mp, MB_TERM_BR, 0); diff --git a/mono/jit/testjit.c b/mono/jit/testjit.c index 3d41ee8a425..fbeba1761e2 100644 --- a/mono/jit/testjit.c +++ b/mono/jit/testjit.c @@ -767,6 +767,22 @@ mono_compile_method (MonoMethod *method) MAKE_BI_ALU (REM) MAKE_BI_ALU (REM_UN) + case CEE_NEG: { + ip++; + sp--; + t1 = ctree_new (mp, MB_TERM_NEG, 0, sp [0], NULL); + t1->cli_addr = sp [0]->cli_addr; + PUSH_TREE (t1); + break; + } + case CEE_NOT: { + ip++; + sp--; + t1 = ctree_new (mp, MB_TERM_NOT, 0, sp [0], NULL); + t1->cli_addr = sp [0]->cli_addr; + PUSH_TREE (t1); + break; + } case CEE_BR_S: { ++ip; t1 = ctree_new_leaf (mp, MB_TERM_BR, 0); diff --git a/mono/jit/x86.brg b/mono/jit/x86.brg index 92cc9d1c3e9..9bb5992b271 100644 --- a/mono/jit/x86.brg +++ b/mono/jit/x86.brg @@ -75,7 +75,7 @@ guint64 mono_llrem_un (guint64 a, guint64 b); # constatnts %term CONST_I4 CONST_I8 CONST_R4 CONST_R8 %term LDLOC LDARG STLOC BR RET RETV ARG CALL BREAK -%term ADD SUB MUL DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN +%term ADD SUB MUL DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT %term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN %term CONV_I4 CONV_I1 CONV_I2 CONV_I8 @@ -283,6 +283,18 @@ reg: XOR (reg, reg) { x86_alu_reg_reg (s->code, X86_XOR, tree->reg1, tree->right->reg1); } +reg: NEG (reg) { + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + x86_neg_reg (s->code, tree->reg1); +} + +reg: NOT (reg) { + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + x86_not_reg (s->code, tree->reg1); +} + reg: SHL (reg, CONST_I4) { if (tree->reg1 != tree->left->reg1) x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); @@ -670,6 +682,11 @@ stmt: CALL { # 64 bit integers # +reg: CONV_I4 (lreg) { + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); +} + lreg: CONST_I8 1 { x86_mov_reg_imm (s->code, tree->reg1, tree->data.i); x86_mov_reg_imm (s->code, tree->reg2, *(gint32 *)(&tree->data.p + 4)); @@ -681,7 +698,7 @@ lreg: CONV_I8 (CONST_I4) 1 { if (tree->left->data.i >= 0) x86_alu_reg_reg (s->code, X86_XOR, tree->reg2, tree->reg2); else - x86_mov_reg_imm (s->code, tree->reg1, -1); + x86_mov_reg_imm (s->code, tree->reg2, -1); } stmt: STLOC (lreg) { @@ -749,6 +766,25 @@ lreg: OR (lreg, lreg) { x86_alu_reg_reg (s->code, X86_OR, tree->reg2, tree->right->reg2); } +lreg: NEG (lreg) { + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + if (tree->reg2 != tree->left->reg2) + x86_mov_reg_reg (s->code, tree->reg2, tree->left->reg2, 4); + x86_neg_reg (s->code, tree->reg1); + x86_alu_reg_imm (s->code, X86_ADC, tree->reg2, 0); + x86_neg_reg (s->code, tree->reg2); +} + +lreg: NOT (lreg) { + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + if (tree->reg2 != tree->left->reg2) + x86_mov_reg_reg (s->code, tree->reg2, tree->left->reg2, 4); + x86_not_reg (s->code, tree->reg1); + x86_not_reg (s->code, tree->reg2); +} + lreg: MUL (lreg, lreg) { if (mono_regset_reg_used (s->rs, X86_ECX)) x86_push_reg (s->code, X86_ECX); @@ -1057,6 +1093,11 @@ stmt: BLE_UN (lreg, lreg) { # # floating point +#stmt: STLOC (CONV_I4 (freg)) { +# // fixme: set CW +# x86_fist_pop_membase (s->code, X86_EBP, tree->data.i, FALSE); +#} + freg: CONST_R4 { x86_fld (s->code, tree->data.p, FALSE); } @@ -1087,6 +1128,28 @@ freg: ADD (freg, freg) { x86_fp_op_reg (s->code, X86_FADD, 1, TRUE); } +freg: SUB (freg, freg) { + x86_fp_op_reg (s->code, X86_FSUB, 1, TRUE); +} + +freg: MUL (freg, freg) { + x86_fp_op_reg (s->code, X86_FMUL, 1, TRUE); +} + +freg: DIV (freg, freg) { + x86_fp_op_reg (s->code, X86_FDIV, 1, TRUE); +} + +#freg: REM (freg, freg) { +# this does not work, since it does not pop a value from the stack, +# and we need to test if the instruction is ready +# x86_fprem1 (s->code); +#} + +freg: NEG (freg) { + x86_fchs (s->code); +} + stmt: STLOC (freg) { g_assert (tree->type == MONO_TYPE_R4 || tree->type == MONO_TYPE_R8); @@ -1113,6 +1176,69 @@ stmt: BEQ (freg, freg) { x86_branch32 (s->code, X86_CC_EQ, tree->data.i - offset, TRUE); } +stmt: BNE_UN (freg, freg) { + guint8 *start = s->code; + gint32 offset; + + tree->is_jump = 1; + x86_fcompp (s->code); + x86_fnstsw (s->code); + x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500); + x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x4000); + offset = 6 + s->code - start; + x86_branch32 (s->code, X86_CC_NE, tree->data.i - offset, TRUE); +} + +stmt: BLT_UN (freg, freg) { + guint8 *start = s->code; + gint32 offset; + + tree->is_jump = 1; + x86_fcompp (s->code); + x86_fnstsw (s->code); + x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500); + x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x0100); + offset = 6 + s->code - start; + x86_branch32 (s->code, X86_CC_EQ, tree->data.i - offset, TRUE); +} + +stmt: BGE_UN (freg, freg) { + guint8 *start = s->code; + gint32 offset; + + tree->is_jump = 1; + x86_fcompp (s->code); + x86_fnstsw (s->code); + x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500); + x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x0100); + offset = 6 + s->code - start; + x86_branch32 (s->code, X86_CC_NE, tree->data.i - offset, TRUE); +} + +stmt: BGT_UN (freg, freg) { + guint8 *start = s->code; + gint32 offset; + + tree->is_jump = 1; + x86_fcompp (s->code); + x86_fnstsw (s->code); + x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500); + offset = 6 + s->code - start; + x86_branch32 (s->code, X86_CC_EQ, tree->data.i - offset, TRUE); +} + +stmt: BLE_UN (freg, freg) { + guint8 *start = s->code; + gint32 offset; + + tree->is_jump = 1; + x86_fcompp (s->code); + x86_fnstsw (s->code); + x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500); + offset = 6 + s->code - start; + x86_branch32 (s->code, X86_CC_NE, tree->data.i - offset, TRUE); +} + freg: CALL { x86_mov_reg_imm (s->code, X86_EAX, tree->data.p); x86_call_membase (s->code, X86_EAX, diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index e726374eaad..e4091eae210 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -1,5 +1,7 @@ TEST_PROG=../interpreter/mint +JITTEST_PROG=../jit/testjit + CSC=csc BENCHSRC=fib.cs random.cs nested-loops.cs @@ -30,9 +32,23 @@ TESTSRC= \ jit-int.cs \ jit-uint.cs \ jit-long.cs \ - jit-ulong.cs + jit-ulong.cs \ + jit-float.cs + + +JITTESTSRC= \ + jit-int.cs \ + jit-uint.cs \ + jit-long.cs \ + jit-ulong.cs \ + jit-float.cs \ + test-ops.cs \ + fib.cs \ + nested-loops.cs \ + random.cs TESTS=$(TESTSRC:.cs=.exe) +JITTESTS=$(JITTESTSRC:.cs=.exe) TESTBS=$(BENCHSRC:.cs=.exe) EXTRA_DIST=test-driver $(TESTSRC) @@ -50,3 +66,7 @@ testb: $(TEST_PROG) $(TESTBS) ./test-driver $(TEST_PROG) $$i; \ done +testjit: $(JITTEST_PROG) $(JITTESTS) + for i in $(JITTESTS); do \ + ./test-driver $(JITTEST_PROG) $$i; \ + done diff --git a/mono/tests/jit-float.cs b/mono/tests/jit-float.cs new file mode 100644 index 00000000000..4dd22530e6a --- /dev/null +++ b/mono/tests/jit-float.cs @@ -0,0 +1,75 @@ +public class TestJit { + + public static double test_call (double a, double b) { + return a+b; + } + + public static int test_alu () + { + double a = 9, b = 6; + + if ((a + b) != 15) + return 1; + + if ((a - b) != 3) + return 1; + + if ((a * b) != 54) + return 1; + + if ((a / 4) != 2.25) + return 1; + + //if ((a % 4) != 1) + // return 1; + + if (-a != -9) + return 1; + + return 0; + } + + public static int test_branch () + { + double a = 5, b = 5, t; + + if (a == b) t = 1; else t = 0; + if (t != 1) return 1; + + if (a != b) t = 0; else t = 1; + if (t != 1) return 1; + + if (a >= b) t = 1; else t = 0; + if (t != 1) return 1; + + if (a > b) t = 0; else t = 1; + if (t != 1) return 1; + + if (a <= b) t = 1; else t = 0; + if (t != 1) return 1; + + if (a < b) t = 0; else t = 1; + if (t != 1) return 1; + + return 0; + } + + public static int Main() { + int num = 1; + + if (test_call (3, 5) != 8) + return num; + num++; + + if (test_branch () != 0) + return num; + num++; + + if (test_alu () != 0) + return num; + num++; + + return 0; + } +} + diff --git a/mono/tests/jit-int.cs b/mono/tests/jit-int.cs index 0a700281062..0542839b866 100644 --- a/mono/tests/jit-int.cs +++ b/mono/tests/jit-int.cs @@ -52,6 +52,13 @@ public class TestJit { if ((a % 4) != 1) return 1; + if (-a != -9) + return 1; + + b = -1; + if (~b != 0) + return 1; + return 0; } diff --git a/mono/tests/jit-long.cs b/mono/tests/jit-long.cs index 8fb77d6b2c2..8a8e5c8e444 100644 --- a/mono/tests/jit-long.cs +++ b/mono/tests/jit-long.cs @@ -29,6 +29,13 @@ public class TestJit { if ((a % 4) != 1) return 1; + if (-a != -9) + return 1; + + b = -1; + if (~b != 0) + return 1; + return 0; } @@ -60,6 +67,8 @@ public class TestJit { public static int Main() { int num = 1; + return test_alu(); + if (test_call (3, 5) != 8) return num; num++; diff --git a/mono/tests/jit-uint.cs b/mono/tests/jit-uint.cs index 0ed685be670..7dd325562ee 100644 --- a/mono/tests/jit-uint.cs +++ b/mono/tests/jit-uint.cs @@ -29,6 +29,10 @@ public class TestJit { if ((a % 4) != 1) return 1; + b = 0; + if (~b != 0xffffffff) + return 1; + return 0; } diff --git a/mono/tests/jit-ulong.cs b/mono/tests/jit-ulong.cs index 41bcc2b5e71..9254919faaf 100644 --- a/mono/tests/jit-ulong.cs +++ b/mono/tests/jit-ulong.cs @@ -29,6 +29,10 @@ public class TestJit { if ((a % 4) != 1) return 1; + b = 0; + if (~b != 0xffffffffffffffff) + return 1; + return 0; } -- 2.25.1