cvsuser     03/02/14 08:31:37

  Modified:    docs/dev jit_i386.dev
               jit/i386 jit_emit.h
               t/op     jit.t
  Log:
  jit_i386: fix unneeded saving of %edx; multiply immediate optimization
  
  Revision  Changes    Path
  1.2       +2 -3      parrot/docs/dev/jit_i386.dev
  
  Index: jit_i386.dev
  ===================================================================
  RCS file: /cvs/public/parrot/docs/dev/jit_i386.dev,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- jit_i386.dev      14 Feb 2003 13:32:01 -0000      1.1
  +++ jit_i386.dev      14 Feb 2003 16:31:33 -0000      1.2
  @@ -289,9 +289,8 @@
   
   =head1 BUGS
   
  -The register <%edx> above was preserved over the vtable calls, though
  -it's unused.  The floating point registers do not get saved to
  -parrots, this assumes, that external routines do preserve the FP stack
  +The floating point registers do not get saved to parrots before vtable
  +calls, this assumes, that external routines do preserve the FP stack
   pointer and don't use more the 4 floating point registers at once.
   
   =head1 AUTHOR
  
  
  
  1.53      +67 -5     parrot/jit/i386/jit_emit.h
  
  Index: jit_emit.h
  ===================================================================
  RCS file: /cvs/public/parrot/jit/i386/jit_emit.h,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -w -r1.52 -r1.53
  --- jit_emit.h        14 Feb 2003 13:32:11 -0000      1.52
  +++ jit_emit.h        14 Feb 2003 16:31:35 -0000      1.53
  @@ -3,7 +3,7 @@
    *
    * i386
    *
  - * $Id: jit_emit.h,v 1.52 2003/02/14 13:32:11 leo Exp $
  + * $Id: jit_emit.h,v 1.53 2003/02/14 16:31:35 leo Exp $
    */
   
   #include <assert.h>
  @@ -617,11 +617,73 @@
       emitm_smull_op(pc); \
       (pc) = emit_r_X((pc), emit_reg(reg1 - 1), b, i, s, (long)d); }
   
  +#ifdef NO_MUL_OPT
   #  define jit_emit_mul_rir_i(pc, reg2, imm, reg1) \
       *(pc++) = 0x69; \
       *(pc++) = 0xc0 | (reg1 - 1) | (reg2 - 1) << 3; \
       *(long *)(pc) = (long)imm; \
       pc += 4
  +#else
  +extern UINTVAL ld(UINTVAL);
  +static char *
  +opt_mul(char *pc, int dest, INTVAL imm, int src)
  +{
  +    UINTVAL ld2 = ld((UINTVAL) imm);
  +
  +    if (imm == 0) {
  +        jit_emit_mov_ri_i(pc, dest, 0);
  +    }
  +    else if (imm > 0 && !(imm & (imm - 1))) {
  +        /* positive power of 2 - do a shift */
  +        jit_emit_mov_rr_i(pc, dest, src);
  +        pc = emit_shift_i_r(pc, emit_b100, ld2, dest);
  +    }
  +    else {
  +        /* special small numbers */
  +        switch (imm) {
  +            case 3:
  +                /* LEA dest, base, index, scale, displace
  +                 * note: src may be dest, so can't be reused
  +                 *
  +                 * dest = src + src*2 */
  +                emitm_lea_m_r(pc, dest, src, src, 2, 0);
  +                break;
  +            case 5:      /* dest = src + src*4 */
  +                emitm_lea_m_r(pc, dest, src, src, 4, 0);
  +                break;
  +            case 6:     /* dest = src*3; dest += dest */
  +                emitm_lea_m_r(pc, dest, src, src, 2, 0);
  +                jit_emit_add_rr_i(pc, dest, dest);
  +                break;
  +            case 9:      /* dest = src + src*8 */
  +                emitm_lea_m_r(pc, dest, src, src, 8, 0);
  +                break;
  +            case 10:      /* dest = src + src*4 ; dest+= dest */
  +                emitm_lea_m_r(pc, dest, src, src, 4, 0);
  +                jit_emit_add_rr_i(pc, dest, dest);
  +                break;
  +            case 12:     /* dest= src*3; dest <<= 2 */
  +                emitm_lea_m_r(pc, dest, src, src, 2, 0);
  +                pc = emit_shift_i_r(pc, emit_b100, 2, dest);
  +                break;
  +            case 100:      /* dest = src + src*4 ; dest <<= 2; dest = 5*dest*/
  +                emitm_lea_m_r(pc, dest, src, src, 4, 0);
  +                pc = emit_shift_i_r(pc, emit_b100, 2, dest);
  +                emitm_lea_m_r(pc, dest, dest, dest, 4, 0);
  +                break;
  +            default:
  +                *(pc++) = 0x69;
  +                *(pc++) = 0xc0 | (src - 1) | (dest - 1) << 3;
  +                *(long *)(pc) = (long)imm;
  +                pc += 4;
  +        }
  +    }
  +    return pc;
  +}
  +#define jit_emit_mul_rir_i(pc, dest, imm, src) \
  +    pc = opt_mul(pc, dest, imm, src)
  +
  +#endif
   
   #  define jit_emit_mul_ri_i(pc, r, imm) jit_emit_mul_rir_i(pc, r, imm, r)
   
  @@ -1747,10 +1809,10 @@
       int st = 0;         /* stack pop correction */
       int saved = 0;
       Parrot_jit_register_usage_t *ru = jit_info->optimizer->cur_section->ru;
  -    /* this is not callee saved, 3 is the # of emit_EDX in intval_map
  +    /* this is not callee saved, emit_EDX is 4th in intval_map
        * should also save floating regs back?
        */
  -    if (ru[0].reg_dir[ru[0].reg_usage[3]]) {
  +    if (ru[0].registers_used == 4) {
           emitm_pushl_r(jit_info->native_ptr, emit_EDX);
           saved = 1;
       }
  @@ -2091,10 +2153,10 @@
       int nvtable = op_jit[*jit_info->cur_op].extcall;
       int saved = 0;
       Parrot_jit_register_usage_t *ru = jit_info->optimizer->cur_section->ru;
  -    /* this is not callee saved, 3 is the # of emit_EDX in intval_map
  +    /* this is not callee saved, emit_EDX is 4th in intval_map
        * should also save floating regs back?
        */
  -    if (ru[0].reg_dir[ru[0].reg_usage[3]]) {
  +    if (ru[0].registers_used == 4) {
           emitm_pushl_r(jit_info->native_ptr, emit_EDX);
           saved = 1;
       }
  
  
  
  1.3       +106 -1    parrot/t/op/jit.t
  
  Index: jit.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/op/jit.t,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- jit.t     14 Feb 2003 13:32:22 -0000      1.2
  +++ jit.t     14 Feb 2003 16:31:37 -0000      1.3
  @@ -1,6 +1,6 @@
   #! perl -w
   # test WRT JIT register allocation
  -use Parrot::Test tests => 42;
  +use Parrot::Test tests => 44;
   
   output_is(<<'CODE', <<'OUTPUT', "add_i_i_i 1,2,3 mapped");
   set I0,0
  @@ -751,3 +751,108 @@
   CODE
   ok 1
   OUTPUT
  +
  +# multiply optimization tests
  +
  +output_is(<<'CODE', <<'OUTPUT', "power of 2");
  +   set I0, 5
  +   mul I1, I0, 0
  +   eq I1, 0, ok_1
  +   print "nok mul 0 "
  +ok_1:
  +   print "ok 1\n"
  +
  +   mul I1, I0, 1
  +   eq I1, 5, ok_2
  +   print "nok mul 1 "
  +ok_2:
  +   print "ok 2\n"
  +
  +   mul I1, I0, 2
  +   eq I1, 10, ok_3
  +   print "nok mul 2 "
  +ok_3:
  +   print "ok 3\n"
  +
  +   mul I1, I0, 4
  +   eq I1, 20, ok_4
  +   print "nok mul 4 "
  +ok_4:
  +   print "ok 4\n"
  +
  +   mul I1, I0, 8
  +   eq I1, 40, ok_5
  +   print "nok mul 8 "
  +ok_5:
  +   print "ok 5\n"
  +
  +   mul I1, I0, 1024
  +   eq I1, 5120, ok_6
  +   print "nok mul 1024 "
  +ok_6:
  +   print "ok 6\n"
  +   end
  +CODE
  +ok 1
  +ok 2
  +ok 3
  +ok 4
  +ok 5
  +ok 6
  +OUTPUT
  +
  +output_is(<<'CODE', <<'OUTPUT', "small imm");
  +   set I0, 5
  +   mul I1, I0, 3
  +   eq I1, 15, ok_1
  +   print "nok mul 3 "
  +ok_1:
  +   print "ok 1\n"
  +
  +   mul I1, I0, 5
  +   eq I1, 25, ok_2
  +   print "nok mul 5 "
  +ok_2:
  +   print "ok 2\n"
  +
  +   mul I1, I0, 6
  +   eq I1, 30, ok_3
  +   print "nok mul 6 "
  +ok_3:
  +   print "ok 3\n"
  +
  +   mul I1, I0, 9
  +   eq I1, 45, ok_4
  +   print "nok mul 9 "
  +ok_4:
  +   print "ok 4\n"
  +
  +   mul I1, I0, 10
  +   eq I1, 50, ok_5
  +   print "nok mul 10 "
  +ok_5:
  +   print "ok 5\n"
  +
  +   mul I1, I0, 12
  +   eq I1, 60, ok_6
  +   print "nok mul 12 "
  +ok_6:
  +   print "ok 6\n"
  +
  +   mul I1, I0, 100
  +   eq I1, 500, ok_7
  +   print "nok mul 100 "
  +ok_7:
  +   print "ok 7\n"
  +
  +   end
  +CODE
  +ok 1
  +ok 2
  +ok 3
  +ok 4
  +ok 5
  +ok 6
  +ok 7
  +OUTPUT
  +
  
  
  


Reply via email to