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
+