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; }
 

Reply via email to