Author: leo
Date: Sun Feb 19 06:16:42 2006
New Revision: 11665
Modified:
trunk/src/jit/i386/core.jit
trunk/t/op/trans.t
Log:
JIT/x86 - implement pow_n_n_i
* it works, but it's disabled as it is slower than the builtin
* test
Modified: trunk/src/jit/i386/core.jit
==============================================================================
--- trunk/src/jit/i386/core.jit (original)
+++ trunk/src/jit/i386/core.jit Sun Feb 19 06:16:42 2006
@@ -1681,6 +1681,78 @@ Parrot_isle_i_nc_n {
iscc_i_xc_x s/<_N>/_n/ s/<cc>/emitm_jbe/ s/<typ>/NUM/ s/<scr>/FSR1/
s/<c>/&NUM/
}
+;
+; this code works, but it's slower than the builtin pow (disabled XXX)
+; TODO check alignment
+;
+Parrot_XXX_pow_n_n_i {
+ int e_reg, saved = 0;
+ char *L1, *L2, *L3, *L4, *L5, *L6;
+
+ if (MAP[2]) {
+ emitm_fld(NATIVECODE, MAP[2]);
+ }
+ else {
+ jit_emit_fload_mb_n(NATIVECODE, emit_EBX, ROFFS_NUM(2));
+ } /* n2 = $2 ST(1) */
+ emitm_fld1(NATIVECODE); /* res = 1.0 ST(0) */
+ if (MAP[3]) {
+ jit_emit_mov_rr_i(NATIVECODE, emit_EAX, MAP[3]);
+ }
+ else {
+ jit_emit_mov_RM_i(NATIVECODE, emit_EAX, ROFFS_INT(3));
+ }
+ jit_emit_test_r_i(NATIVECODE, emit_EAX); /* e == 0? */
+ L1 = NATIVECODE;
+ emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L1 */
+ if (intreg_is_used(jit_info, emit_ECX)) {
+ emitm_pushl_r(NATIVECODE, emit_ECX);
+ saved = 1;
+ }
+ jit_emit_mov_ri_i(NATIVECODE, emit_ECX, 1); /* s = 1 */
+ L2 = NATIVECODE;
+ emitm_jxs(NATIVECODE, emitm_jg, 0); /* jg L2 */
+ jit_emit_neg_r_i(NATIVECODE, emit_ECX); /* s = -1 */
+ jit_emit_neg_r_i(NATIVECODE, emit_EAX); /* e = -e */
+ L2[1] = NATIVECODE - L2 - 2; /* L2: */
+ /* L3: while (e) */
+ jit_emit_test_r_i(NATIVECODE, emit_EAX); /* e == 0? */
+ L3 = NATIVECODE;
+ L4 = NATIVECODE;
+ emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L4 */
+ jit_emit_test_ri_i(NATIVECODE, emit_EAX, 1); /* e & 1 ? */
+ L5 = NATIVECODE;
+ emitm_jxs(NATIVECODE, emitm_jz, 0); /* jz L5 */
+ emitm_fmul(NATIVECODE, 1); /* res *= n2 */
+ jit_emit_dec_r_i(NATIVECODE, emit_EAX); /* --e */
+ /* dec and lsr are setting flags - branch past test at L3 */
+ emitm_jumps(NATIVECODE, L3 - NATIVECODE - 1); /* jmp L3 */
+ /* L5: */
+ L5[1] = NATIVECODE - L5 - 2; /* L5: */
+ jit_emit_mul_rr_n(NATIVECODE, 1, 1); /* n2 *= n2 */
+ jit_emit_lsr_ri_i(NATIVECODE, emit_EAX, 1); /* e >>= 1 */
+ emitm_jumps(NATIVECODE, L3 - NATIVECODE - 1); /* jmp L3 */
+ /* endwhile */
+ L1[1] = NATIVECODE - L1 - 2; /* L2: */
+ L4[1] = NATIVECODE - L4 - 2; /* L4: */
+ jit_emit_test_r_i(NATIVECODE, emit_ECX); /* s ? */
+ L6 = NATIVECODE;
+ emitm_jxs(NATIVECODE, emitm_jg, 0); /* jg L6 */
+ emitm_fld1(NATIVECODE); /* push 1.0 */
+ emitm_fxch(NATIVECODE, 1);
+ emitm_fdivp(NATIVECODE, 1); /* res = 1.0/res */
+ L6[1] = NATIVECODE - L6 - 2; /* L6: */
+ if (MAP[1]) {
+ emitm_fstp(NATIVECODE, (MAP[1] + 2));
+ }
+ else {
+ jit_emit_fstore_m_n(NATIVECODE, ROFFS_NUM(1));
+ }
+ emitm_fstp(NATIVECODE, 0); /* pop 0 */
+ if (saved)
+ emitm_popl_r(NATIVECODE, emit_ECX);
+}
+
/*
* Local variables:
* c-indentation-style: bsd
Modified: trunk/t/op/trans.t
==============================================================================
--- trunk/t/op/trans.t (original)
+++ trunk/t/op/trans.t Sun Feb 19 06:16:42 2006
@@ -636,7 +636,7 @@ ok 1
ok 2
OUTPUT
-pasm_output_is( <<'CODE', <<OUTPUT, "sqrt" );
+pasm_output_is( <<'CODE', <<OUTPUT, "pow_n_n_ic" );
set N0, 2.0
pow N1, N0, 0
print N1
@@ -691,6 +691,77 @@ CODE
0.062500
OUTPUT
+pasm_output_is( <<'CODE', <<OUTPUT, "pow_n_n_i" );
+ set N0, 2.0
+ set I0, 0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ inc I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ set I0, -1
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ dec I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ dec I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ dec I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ dec I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ dec I0
+ pow N1, N0, I0
+ print N1
+ print "\n"
+ end
+CODE
+1.000000
+2.000000
+4.000000
+8.000000
+16.000000
+32.000000
+64.000000
+0.500000
+0.250000
+0.125000
+0.062500
+0.031250
+0.015625
+OUTPUT
+
## remember to change the number of tests :-)
-BEGIN { plan tests => 20; }
+BEGIN { plan tests => 21; }