cvsuser 03/02/18 12:19:11
Modified: . MANIFEST
jit/i386 core.jit jit_emit.h
t/op jit.t
Added: examples/benchmarks primes.c primes.pasm primes.pl primes2.c
primes2.pasm primes2.py
Log:
primes-benchmarks, thanks to Tupshin Harper; faster div jit
Revision Changes Path
1.316 +6 -0 parrot/MANIFEST
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.315
retrieving revision 1.316
diff -u -w -r1.315 -r1.316
--- MANIFEST 18 Feb 2003 12:39:14 -0000 1.315
+++ MANIFEST 18 Feb 2003 20:19:05 -0000 1.316
@@ -205,6 +205,12 @@
examples/benchmarks/gc_waves_headers.pasm
examples/benchmarks/gc_waves_sizeable_data.pasm
examples/benchmarks/gc_waves_sizeable_headers.pasm
+examples/benchmarks/primes.c
+examples/benchmarks/primes.pasm
+examples/benchmarks/primes.pl
+examples/benchmarks/primes2.c
+examples/benchmarks/primes2.pasm
+examples/benchmarks/primes2.pl
examples/benchmarks/stress.pasm
examples/benchmarks/stress.pl
examples/benchmarks/stress2.pasm
1.1 parrot/examples/benchmarks/primes.c
Index: primes.c
===================================================================
#include <stdio.h>
int main()
{
int I1 = 1;
int I2 = 50000;
int I3;
int I4;
int I5;
int I6 = 0;
int I7;
printf("N primes up to ");
printf("%d", I2);
printf(" is: ");
REDO:
I3 = 2;
I4 = I1 / 2;
LOOP:
I5 = I1 % I3;
if (I5) {goto OK;}
goto NEXT;
OK:
I3++;
if (I3 <= I4) {goto LOOP;}
I6++;
I7 = I1;
NEXT:
I1++;
if (I1 <= I2) {goto REDO;}
printf("%d\n", I6);
printf("last is: %d\n", I7);
}
1.1 parrot/examples/benchmarks/primes.pasm
Index: primes.pasm
===================================================================
# Some simple code to print out the primes up to 100
# Leon Brocard <[EMAIL PROTECTED]>
# I1 holds the number we're currently checking for primality
set I1, 1
# I2 holds the highest number we want to check for primality
set I2, 50000
set I6, 0
print "N primes up to "
print I2
print " is: "
time N10
# I1 counts up to I2
REDO: # I3 counts from 2 up to I4 (I1/2)
set I3, 2
div I4, I1, 2
LOOP: # Check if I3 is a factor of I1
cmod I5, I1, I3
if I5, OK
# We've found a factor, so it can't be a prime and
# we can skip right out of this loop and to the next
# number
branch NEXT
OK: inc I3
le I3, I4, LOOP
# We haven't found a factor so it must be a prime
inc I6
set I7, I1
# print I1
# print "\n" # to get them all
NEXT: # Move on to the next number
inc I1
le I1, I2, REDO
time N11
print I6
print "\nlast is: "
print I7
print "\n"
sub N11, N10
print "Elapsed time: "
print N11
print "\n"
end
1.1 parrot/examples/benchmarks/primes.pl
Index: primes.pl
===================================================================
#!/usr/bin/perl
my $i1 = 1;
my $i2 = 50000;
my $i3;
my $i4;
my $i5;
my $i6 = 0;
my $i7;
printf("N primes up to ");
printf("%d", $i2);
printf(" is: ");
REDO:
$i3 = 2;
$i4 = $i1 / 2;
LOOP:
$i5 = $i1 % $i3;
if ($i5) {goto OK;}
goto NEXT;
OK:
$i3++;
if ($i3 <= $i4) {goto LOOP;}
$i6++;
$i7 = $i1;
NEXT:
$i1++;
if ($i1 <= $i2) {goto REDO;}
print $i6, "\nlast is: $i7\n"
1.1 parrot/examples/benchmarks/primes2.c
Index: primes2.c
===================================================================
int main(){
int i=0, max=10000;
int i6 = 0;
int i7;
while (1) {
if (isprime1(i)) {
i7 = i;
i6++;
}
i++;
if (i==max){
break;
}
}
printf("N primes calculated to %d is %d\nlast is: %d\n",max,i6,i7);
}
int isprime1(int input)
{
int n;
if (input < 1) {
return 0;
}
n = input - 1;
while (n > 1){
if (input%n == 0) return 0;
n--;
}
return 1;
}
1.1 parrot/examples/benchmarks/primes2.pasm
Index: primes2.pasm
===================================================================
set I1, 0
set I3, 0
set I4, 10000
LOOP:
save I1
bsr PRIMECHECK
restore I9
unless I9, NOTPRIME
#ISPRIME:
inc I6
set I7, I1
NOTPRIME:
inc I1
ne I1,I4, LOOP
DONE:
print"N primes calculated to "
print I1
print " is "
print I6
print "\n"
print "last is: "
print I7
print "\n"
end
PRIMECHECK:
saveall
restore I5
lt I5,1,ret0
set I6,I5
dec I6
NLOOP:
le I6, 1, ret1
cmod I7, I5, I6
eq I7, 0, ret0
dec I6
branch NLOOP
# is prime
ret1:
set I0, 1
save I0
restoreall
ret
ret0:
set I0, 0
save I0
restoreall
ret
1.1 parrot/examples/benchmarks/primes2.py
Index: primes2.py
===================================================================
import os,sys
def isprime1(input):
if input < 1:
return 0
n = input-1
while n > 1:
if input%n == 0:
return 0
n = n - 1
return 1
def main():
i = 0
l = 0
i6 = 0
i7 = 0
max = 10000
while 1:
if isprime1(i):
i6 = i6 + 1
i7 = i
i = i + 1
if i == max:
break
print "N primes calculated to ",max, i6
print "last is:", i7
if __name__ == "__main__":
main()
1.41 +77 -7 parrot/jit/i386/core.jit
Index: core.jit
===================================================================
RCS file: /cvs/public/parrot/jit/i386/core.jit,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -w -r1.40 -r1.41
--- core.jit 14 Feb 2003 13:32:11 -0000 1.40
+++ core.jit 18 Feb 2003 20:19:08 -0000 1.41
@@ -1,7 +1,7 @@
;
; i386/core.jit
;
-; $Id: core.jit,v 1.40 2003/02/14 13:32:11 leo Exp $
+; $Id: core.jit,v 1.41 2003/02/18 20:19:08 leo Exp $
;
# TODO complete this
@@ -129,12 +129,33 @@
}
}
+TEMPLATE Parrot_divop_x_x {
+ if (MAP[1]) {
+ jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[1]);
+ }
+ else {
+ jit_emit_mov_rm<_N>(NATIVECODE, ISR1, &INT_REG[1]);
+ }
+ if (MAP[2]) {
+ jit_emit_<op>_rr<_N>(NATIVECODE, ISR1, MAP[2]);
+ }
+ else {
+ jit_emit_<op>_rm<_N>(NATIVECODE, ISR1, &INT_REG[2]);
+ }
+ if (MAP[1]) {
+ jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
+ }
+ else {
+ jit_emit_mov_mr<_N>(NATIVECODE, &INT_REG[1], ISR1);
+ }
+}
+
Parrot_mul_i_i {
Parrot_binop_x_x s/<op>/mul/ s/<_N>/_i/
}
Parrot_div_i_i {
- Parrot_binop_x_x s/<op>/div/ s/<_N>/_i/
+ Parrot_divop_x_x s/<op>/div/ s/<_N>/_i/
}
Parrot_add_i_i {
@@ -245,7 +266,19 @@
}
Parrot_div_i_ic {
- Parrot_binop_x_xc s/<_N>/_i/ s/<op>/div/ s/<typ>/*INT/
+ if (MAP[1]) {
+ jit_emit_mov_rr_i(NATIVECODE, ISR1, MAP[1]);
+ }
+ else {
+ jit_emit_mov_rm_i(NATIVECODE, ISR1, &INT_REG[1]);
+ }
+ jit_emit_div_ri_i(NATIVECODE, ISR1, *INT_CONST[2]);
+ if (MAP[1]) {
+ jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
+ }
+ else {
+ jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
+ }
}
Parrot_add_n_nc {
@@ -387,6 +420,22 @@
}
}
+TEMPLATE Parrot_divop_x_x_xc {
+ if (MAP[2]) {
+ jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
+ }
+ else {
+ jit_emit_mov_rm<_N>(NATIVECODE, ISR1, &INT_REG[2]);
+ }
+ jit_emit_<op>_ri<_N>(NATIVECODE, ISR1, <typ>_CONST[3]);
+ if (MAP[1]) {
+ jit_emit_mov_rr_i(NATIVECODE, MAP[1], ISR1);
+ }
+ else {
+ jit_emit_mov_mr_i(NATIVECODE, &INT_REG[1], ISR1);
+ }
+}
+
Parrot_add_i_i_ic {
Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/add/ s/<typ>/*INT/
}
@@ -404,7 +453,7 @@
}
Parrot_div_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/div/ s/<typ>/*INT/
+ Parrot_divop_x_x_xc s/<_N>/_i/ s/<op>/div/ s/<typ>/*INT/
}
Parrot_mul_n_n_nc {
@@ -416,7 +465,7 @@
}
Parrot_cmod_i_i_ic {
- Parrot_binop_x_x_xc s/<_N>/_i/ s/<op>/cmod/ s/<typ>/*INT/
+ Parrot_divop_x_x_xc s/<_N>/_i/ s/<op>/cmod/ s/<typ>/*INT/
}
Parrot_cmod_n_n_nc {
@@ -590,6 +639,27 @@
}
}
+TEMPLATE Parrot_divop_x_x_x {
+ if (MAP[2]) {
+ jit_emit_mov_rr<_N>(NATIVECODE, ISR1, MAP[2]);
+ }
+ else {
+ jit_emit_mov_rm<_N>(NATIVECODE, ISR1, &INT_REG[2]);
+ }
+ if (MAP[3]) {
+ jit_emit_<op>_rr<_N>(NATIVECODE, ISR1, MAP[3]);
+ }
+ else {
+ jit_emit_<op>_rm<_N>(NATIVECODE, ISR1, &INT_REG[3]);
+ }
+ if (MAP[1]) {
+ jit_emit_mov_rr<_N>(NATIVECODE, MAP[1], ISR1);
+ }
+ else {
+ jit_emit_mov_mr<_N>(NATIVECODE, &INT_REG[1], ISR1);
+ }
+}
+
Parrot_mul_i_i_i {
Parrot_binop_x_x_x s/<op>/mul/ s/<_N>/_i/
}
@@ -603,7 +673,7 @@
}
Parrot_div_i_i_i {
- Parrot_binop_x_x_x s/<op>/div/ s/<_N>/_i/
+ Parrot_divop_x_x_x s/<op>/div/ s/<_N>/_i/
}
Parrot_bor_i_i_i {
@@ -631,7 +701,7 @@
}
Parrot_cmod_i_i_i {
- Parrot_binop_x_x_x s/<op>/cmod/ s/<_N>/_i/
+ Parrot_divop_x_x_x s/<op>/cmod/ s/<_N>/_i/
}
Parrot_sub_n_n_n {
1.54 +122 -4 parrot/jit/i386/jit_emit.h
Index: jit_emit.h
===================================================================
RCS file: /cvs/public/parrot/jit/i386/jit_emit.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -w -r1.53 -r1.54
--- jit_emit.h 14 Feb 2003 16:31:35 -0000 1.53
+++ jit_emit.h 18 Feb 2003 20:19:08 -0000 1.54
@@ -3,7 +3,7 @@
*
* i386
*
- * $Id: jit_emit.h,v 1.53 2003/02/14 16:31:35 leo Exp $
+ * $Id: jit_emit.h,v 1.54 2003/02/18 20:19:08 leo Exp $
*/
#include <assert.h>
@@ -12,6 +12,8 @@
# define JIT_CGP
#endif
+extern UINTVAL ld(UINTVAL);
+
/* #define NEG_MINUS_ZERO */
#define NEG_ZERO_SUB
@@ -485,6 +487,7 @@
# define jit_emit_cdq(pc) *(pc)++ = 0x99
+#if 0
# define jit_emit_div_rr_i(pc, r1, r2) { \
if (r1 == r2) { \
jit_emit_mov_ri_i(pc, r1, 1); \
@@ -531,6 +534,60 @@
} \
}
+#else
+static char *
+opt_div_rr(Parrot_jit_info_t *jit_info, int dest, int src, int is_div)
+{
+ char *pc = jit_info->native_ptr;
+ int saved = 0;
+ if (dest != emit_EAX) {
+ jit_emit_mov_rr_i(pc, emit_EAX, dest);
+ }
+ /* if EDX is mapped, save it to ECX */
+ if (jit_info->optimizer->cur_section->ru[0].registers_used == 4) {
+ saved = 1;
+ jit_emit_mov_rr_i(pc, emit_ECX, emit_EDX);
+ }
+#if 0
+ jit_emit_cdq(pc);
+#else
+ /* this sequence allows 2 other instructions to run parallel */
+ jit_emit_mov_rr_i(pc, emit_EDX, emit_EAX);
+ pc = emit_shift_i_r(pc, emit_b111, 31, emit_EDX); /* SAR 31 */
+#endif
+ if (src == emit_EDX) {
+ assert(saved);
+ emitm_sdivl_r(pc, emit_ECX);
+ }
+ else {
+ emitm_sdivl_r(pc, src);
+ }
+ if (is_div) {
+ /* result = quotient in EAX */
+ if (saved) {
+ jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
+ }
+ if (dest != emit_EAX) {
+ jit_emit_mov_rr_i(pc, dest, emit_EAX);
+ }
+ }
+ else {
+ /* result = remainder in EDX */
+ if (dest != emit_EDX) {
+ jit_emit_mov_rr_i(pc, dest, emit_EDX);
+ if (saved) {
+ jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
+ }
+ }
+ }
+ return pc;
+}
+
+# define jit_emit_div_rr_i(pc, r1, r2) pc = opt_div_rr(jit_info, r1, r2, 1)
+# define jit_emit_cmod_rr_i(pc, r1, r2) pc = opt_div_rr(jit_info, r1, r2, 0)
+#endif
+
+#if 0
# define jit_emit_div_ri_i(pc, r1, imm) { \
if (r1 != emit_EAX) { \
jit_emit_mov_rr_i(pc, emit_EAX, r1); \
@@ -555,6 +612,56 @@
} \
}
+#else
+static char *
+opt_div_ri(Parrot_jit_info_t *jit_info, int dest, INTVAL imm)
+{
+ char *pc = jit_info->native_ptr;
+
+ UINTVAL ld2 = ld((UINTVAL) imm);
+ if (imm > 1 && !(imm & (imm - 1))) {
+ /* positive power of 2 - do a shift */
+ pc = emit_shift_i_r(pc, emit_b101, ld2, dest);
+ }
+ else {
+ int saved = 0;
+ if (dest != emit_EAX) {
+ jit_emit_mov_rr_i(pc, emit_EAX, dest);
+ }
+ if (jit_info->optimizer->cur_section->ru[0].registers_used == 4) {
+ saved = 1;
+ jit_emit_mov_rr_i(pc, emit_ECX, emit_EDX);
+ }
+ jit_emit_cdq(pc);
+ if (!saved) { /* use ECX for imm */
+ jit_emit_mov_ri_i(pc, emit_ECX, imm);
+ emitm_sdivl_r(pc, emit_ECX);
+ }
+ else {
+ if (dest != emit_EBX) {
+ emitm_pushl_r(pc, emit_EBX);
+ jit_emit_mov_ri_i(pc, emit_EBX, imm);
+ emitm_sdivl_r(pc, emit_EBX);
+ pc = emit_popl_r(pc, emit_EBX);
+ }
+ else {
+ emitm_pushl_r(pc, emit_EDI);
+ jit_emit_mov_ri_i(pc, emit_EDI, imm);
+ emitm_sdivl_r(pc, emit_EDI);
+ pc = emit_popl_r(pc, emit_EDI);
+ }
+ jit_emit_mov_rr_i(pc, emit_EDX, emit_ECX);
+ }
+ if (dest != emit_EAX) {
+ jit_emit_mov_rr_i(pc, dest, emit_EAX);
+ }
+ }
+ return pc;
+}
+
+# define jit_emit_div_ri_i(pc, r1, imm) pc = opt_div_ri(jit_info, r1, imm)
+#endif
+
# define jit_emit_cmod_ri_i(pc, r1, imm) { \
if (r1 != emit_EAX) { \
jit_emit_mov_rr_i(pc, emit_EAX, r1); \
@@ -624,7 +731,6 @@
*(long *)(pc) = (long)imm; \
pc += 4
#else
-extern UINTVAL ld(UINTVAL);
static char *
opt_mul(char *pc, int dest, INTVAL imm, int src)
{
@@ -2582,12 +2688,24 @@
/*
* if jit_emit_noop is defined, it does align a jump target
- * to 1 << JUMP_ALIGN (it should emit exactly 1 byte)
+ * to 1 << JUMP_ALIGN
+ * It may emit exactly one byte, or some desired padding.
+ * The instructions must perfomr like a noop.
+ *
*
* s. also info gcc /align-jump
+ *
+ * noop; mov %esi, %esi; lea 0(%esi), %esi
*/
-#define jit_emit_noop(pc) *pc++ = 0x90;
+#define jit_emit_noop(pc) do { \
+ switch ( ((unsigned long) pc) & 3) { \
+ case 1: *pc++ = 0x8d; *pc++ = 0x76; *pc++ = 0x00; break; \
+ case 2: *pc++ = 0x89; *pc++ = 0xf6; break; \
+ case 3: *pc++ = 0x90; break; \
+ } \
+} while (0)
+
#define JUMP_ALIGN 2
/* registers are either allocate per section or per basic block
1.4 +265 -2 parrot/t/op/jit.t
Index: jit.t
===================================================================
RCS file: /cvs/public/parrot/t/op/jit.t,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- jit.t 14 Feb 2003 16:31:37 -0000 1.3
+++ jit.t 18 Feb 2003 20:19:10 -0000 1.4
@@ -1,6 +1,6 @@
#! perl -w
# test WRT JIT register allocation
-use Parrot::Test tests => 44;
+use Parrot::Test tests => 57;
output_is(<<'CODE', <<'OUTPUT', "add_i_i_i 1,2,3 mapped");
set I0,0
@@ -540,6 +540,237 @@
00
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 1,2,3 mapped");
+set I0,0
+set I1,6
+set I2,2
+div I0,I1,I2
+print I0
+print I1
+print I2
+print "\n"
+end
+CODE
+362
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 1,2 mapped");
+set I0,0
+set I1,8
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I0,I1,I4
+print I0
+print I1
+print I4
+print "\n"
+end
+CODE
+284
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 1,3 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I0,I4,I1
+print I0
+print I4
+print I1
+print "\n"
+end
+CODE
+441
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 2,3 mapped");
+set I0,0
+set I1,9
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I4,I1,I3
+print I4
+print I1
+print I3
+print "\n"
+end
+CODE
+393
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 1 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I1,I5,I4
+print I1
+print I5
+print I4
+print "\n"
+end
+CODE
+004
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 2 mapped");
+set I0,0
+set I1,8
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I5,I1,I4
+print I5
+print I1
+print I4
+print "\n"
+end
+CODE
+284
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 3 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I5,I4,I1
+print I5
+print I1
+print I4
+print "\n"
+end
+CODE
+414
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i_i 0 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,3
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I5,I6,I4
+print I5
+print I6
+print I4
+print "\n"
+end
+CODE
+004
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i 1,2 mapped");
+set I0,0
+set I1,1
+set I2,9
+set I3,9
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I2, I3
+print I2
+print I3
+print "\n"
+end
+CODE
+19
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i 1 mapped");
+set I0,0
+set I1,1
+set I2,8
+set I3,8
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I2, I4
+print I2
+print I4
+print "\n"
+end
+CODE
+24
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i 2 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,2
+set I4,4
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I4, I2
+print I4
+print I2
+print "\n"
+end
+CODE
+22
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "div_i_i 0 mapped");
+set I0,0
+set I1,1
+set I2,2
+set I3,3
+set I4,4
+set I5,1
+set I0,I1
+set I2,I3
+set I0,I1
+set I2,I3
+div I4, I5
+print I4
+print I5
+print "\n"
+end
+CODE
+41
+OUTPUT
+
# tests for JIT CGP
output_is(<<'CODE', <<'OUTPUT', "1 non jit");
set I0, 16
@@ -754,7 +985,7 @@
# multiply optimization tests
-output_is(<<'CODE', <<'OUTPUT', "power of 2");
+output_is(<<'CODE', <<'OUTPUT', "mul power of 2");
set I0, 5
mul I1, I0, 0
eq I1, 0, ok_1
@@ -856,3 +1087,35 @@
ok 7
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "div power of 2");
+ set I0, 1024
+ div I1, I0, 2
+ eq I1, 512, ok_1
+ print "nok div 2 "
+ok_1:
+ print "ok 1\n"
+
+ div I1, I0, 4
+ eq I1, 256, ok_2
+ print "nok div 4 "
+ok_2:
+ print "ok 2\n"
+
+ div I1, I0, 8
+ eq I1, 128, ok_3
+ print "nok div 8 "
+ok_3:
+ print "ok 3\n"
+
+ div I1, I0, 16
+ eq I1, 64, ok_4
+ print "nok div 16 "
+ok_4:
+ print "ok 4\n"
+ end
+CODE
+ok 1
+ok 2
+ok 3
+ok 4
+OUTPUT