903 lines
15 KiB
Plaintext
903 lines
15 KiB
Plaintext
// | _ _ _ _ |
|
|
// | _ __ ___ __ _ _ __ __| | ___| | |__ _ __ ___ __ _ __| | |
|
|
// | | '_ ` _ \ / _` | '_ \ / _` |/ _ \ | '_ \| '__/ _ \/ _` |/ _` | |
|
|
// | | | | | | | (_| | | | | (_| | __/ | |_) | | | __/ (_| | (_| | |
|
|
// | |_| |_| |_|\__,_|_| |_|\__,_|\___|_|_.__/|_| \___|\__,_|\__,_| |
|
|
// | |
|
|
// | This is mandelbread, the fractal renderer, written in IJVM. |
|
|
// | Made by Arthur de Fluiter, 2k19 |
|
|
//
|
|
// Requirements:
|
|
// - Full instruction set implementation
|
|
// -> (everything except IN, NOP, WIDE or bonusses)
|
|
// - A relatively fast IJVM (runs for about 2-8 sec on good implementation)
|
|
//
|
|
// ;;
|
|
// ;i1;t1@
|
|
// ;i1fi;
|
|
// ;ti1f@@ti;;
|
|
// ;if@@@@@@@@L
|
|
// ;;i@@@@@@@@@i;
|
|
// 1;;0i;;;iii1tG@@@@@G1ii;i; ;;
|
|
// ;@G@G@1t@@@@@@@@@@@@@@@G@fi;L1i1i;
|
|
// ;;i@@@@@@@@@@@@@@@@@@@@@@@@@f@@@@11
|
|
// ;C1tL@@@@@@@@@@@@@@@@@@@@@@@@@@@@f;
|
|
// ; ;;f@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;;
|
|
// ;t;; ;1;; ;;;1L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@L@;
|
|
// ;1tCf1i1fG1fi;;;;i@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i
|
|
// ;;10@@8@@@@@@G111t@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@11
|
|
// ;;f1f@@@@@@@@@@@@Gf8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1;
|
|
// ;@iii10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@fi
|
|
// ;;i1L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@f;
|
|
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@fi;
|
|
// ;;i1L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@f;
|
|
// ;@iii10@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@fi
|
|
// ;;f1f@@@@@@@@@@@@Gf8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1;
|
|
// ;;10@@8@@@@@@G111t@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@11
|
|
// ;1tCf1i1fG1fi;;;;i@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i
|
|
// ;t;; ;1;; ;;;1L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@L@;
|
|
// ; ;;f@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;;
|
|
// ;C1tL@@@@@@@@@@@@@@@@@@@@@@@@@@@@f;
|
|
// ;;i@@@@@@@@@@@@@@@@@@@@@@@@@f@@@@11
|
|
// ;@G@G@1t@@@@@@@@@@@@@@@G@fi;L1i1i;
|
|
// 1;;0i;;;iii1tG@@@@@G1ii;i; ;;
|
|
// ;;i@@@@@@@@@i;
|
|
// ;if@@@@@@@@L
|
|
// ;ti1f@@ti;;
|
|
// ;i1fi;
|
|
// ;i1;t1@
|
|
// ;;
|
|
//
|
|
|
|
.constant
|
|
B00000002 0x00000002
|
|
B00000008 0x00000008
|
|
B0000000C 0x0000000c
|
|
B00000020 0x00000020
|
|
B00000080 0x00000080
|
|
B000000C0 0x000000c0
|
|
B000000F0 0x000000f0
|
|
B00000100 0x00000100
|
|
B00000200 0x00000200
|
|
B00000400 0x00000400
|
|
B00000800 0x00000800
|
|
B00000C00 0x00000c00
|
|
B00001000 0x00001000
|
|
B00002000 0x00002000
|
|
B00004000 0x00004000
|
|
B00008000 0x00008000
|
|
B0000C000 0x0000c000
|
|
B0000F000 0x0000f000
|
|
B0000FF00 0x0000ff00
|
|
B00010000 0x00010000
|
|
B00020000 0x00020000
|
|
B00040000 0x00040000
|
|
B00080000 0x00080000
|
|
B000C0000 0x000c0000
|
|
B00100000 0x00100000
|
|
B00200000 0x00200000
|
|
B00400000 0x00400000
|
|
B00800000 0x00800000
|
|
B00C00000 0x00c00000
|
|
B00F00000 0x00f00000
|
|
B01000000 0x01000000
|
|
B02000000 0x02000000
|
|
B04000000 0x04000000
|
|
B08000000 0x08000000
|
|
B0C000000 0x0c000000
|
|
B10000000 0x10000000
|
|
B20000000 0x20000000
|
|
B40000000 0x40000000
|
|
B80000000 0x80000000
|
|
BC0000000 0xc0000000
|
|
BF0000000 0xf0000000
|
|
BFF000000 0xff000000
|
|
BFFFF0000 0xffff0000
|
|
BITMASK_INVSIGN 0x7fffffff
|
|
BITMASK_SIGNBIT 0x80000000
|
|
INV_FFF 0xfffff000
|
|
MAX_ITERATIONS 30
|
|
MULTIPLIER 256
|
|
MULTIPLIERDIV2 128
|
|
W_HEIGHT 40
|
|
W_WIDTH 100
|
|
X_MAX 128
|
|
X_MIN -512
|
|
Y_MAX 320
|
|
Y_MIN -320
|
|
_OBJREF 0xdeadc001
|
|
.end-constant
|
|
|
|
.main
|
|
LDC_W _OBJREF
|
|
INVOKEVIRTUAL _main
|
|
IFEQ success
|
|
error:
|
|
ERR
|
|
success:
|
|
HALT
|
|
.end-main
|
|
|
|
.method _main()
|
|
.var
|
|
x_range
|
|
y_range
|
|
x
|
|
y
|
|
px
|
|
py
|
|
.end-var
|
|
|
|
BIPUSH 0
|
|
ISTORE px
|
|
BIPUSH 0
|
|
ISTORE py
|
|
|
|
LDC_W X_MAX
|
|
LDC_W X_MIN
|
|
ISUB
|
|
ISTORE x_range
|
|
LDC_W Y_MAX
|
|
LDC_W Y_MIN
|
|
ISUB
|
|
ISTORE y_range
|
|
GOTO loop_y
|
|
|
|
loop_y_update:
|
|
IINC py 1
|
|
ILOAD py
|
|
LDC_W W_HEIGHT
|
|
IF_ICMPEQ loop_y_done
|
|
|
|
loop_y:
|
|
// calculate value of y for pixel py
|
|
LDC_W Y_MIN
|
|
LDC_W _OBJREF
|
|
LDC_W _OBJREF
|
|
ILOAD y_range
|
|
ILOAD py
|
|
INVOKEVIRTUAL mul
|
|
LDC_W W_HEIGHT
|
|
INVOKEVIRTUAL div
|
|
IADD
|
|
ISTORE y
|
|
GOTO loop_x
|
|
|
|
loop_x_update:
|
|
IINC px 1
|
|
ILOAD px
|
|
LDC_W W_WIDTH
|
|
IF_ICMPEQ loop_x_done
|
|
|
|
loop_x:
|
|
// x = x_min + x_range * px / width
|
|
LDC_W X_MIN
|
|
LDC_W _OBJREF
|
|
LDC_W _OBJREF
|
|
ILOAD x_range
|
|
ILOAD px
|
|
INVOKEVIRTUAL mul
|
|
LDC_W W_WIDTH
|
|
INVOKEVIRTUAL div
|
|
IADD
|
|
ISTORE x
|
|
|
|
LDC_W _OBJREF
|
|
ILOAD x
|
|
ILOAD y
|
|
INVOKEVIRTUAL mandelbrot_print
|
|
POP
|
|
GOTO loop_x_update
|
|
|
|
loop_x_done:
|
|
BIPUSH 0
|
|
ISTORE px
|
|
BIPUSH 10
|
|
OUT
|
|
GOTO loop_y_update
|
|
|
|
loop_y_done:
|
|
BIPUSH 0
|
|
IRETURN
|
|
.end-method
|
|
|
|
.method div(a, b)
|
|
.var
|
|
signed
|
|
res
|
|
k
|
|
bshift
|
|
.end-var
|
|
// store the signed state
|
|
BIPUSH 0
|
|
ISTORE signed
|
|
|
|
// get absolute of a and b
|
|
ha:
|
|
ILOAD a
|
|
IFLT negate_a
|
|
hb:
|
|
ILOAD b
|
|
IFLT negate_b
|
|
handled:
|
|
|
|
BIPUSH 0
|
|
ISTORE res
|
|
|
|
// edge case if a < b, we're done
|
|
ILOAD a
|
|
ILOAD b
|
|
ISUB
|
|
IFLT apply_sign
|
|
|
|
// edge case if b == 0, we error
|
|
ILOAD b
|
|
IFEQ division_by_zero
|
|
|
|
BIPUSH 1
|
|
ISTORE k
|
|
ILOAD b
|
|
ISTORE bshift
|
|
|
|
// build a stack of kn, kn * b, kn-1, kn-1 * b, ..., k0 (1), k0 * b (b)
|
|
build_stack:
|
|
ILOAD a
|
|
ILOAD bshift
|
|
ISUB
|
|
IFLT stack_unwind
|
|
|
|
// push bshift to stack and bshift += bshift
|
|
ILOAD bshift
|
|
DUP
|
|
DUP
|
|
IADD
|
|
ISTORE bshift
|
|
|
|
// push k to stack and k += k
|
|
ILOAD k
|
|
DUP
|
|
DUP
|
|
IADD
|
|
ISTORE k
|
|
GOTO build_stack
|
|
|
|
stack_unwind:
|
|
ISTORE k // stores k from (k * b) in size
|
|
|
|
// a - (k * b)
|
|
ILOAD a
|
|
SWAP
|
|
ISUB
|
|
|
|
// duplicate a - (k * b) on stack
|
|
DUP
|
|
|
|
// if (a - (k * b) < 0) cant_substract
|
|
IFLT cant_substract
|
|
|
|
substract:
|
|
// store a = a - k * b
|
|
ISTORE a
|
|
|
|
// calculate res
|
|
ILOAD res
|
|
ILOAD k
|
|
IADD
|
|
ISTORE res
|
|
|
|
ILOAD k
|
|
BIPUSH 1
|
|
IF_ICMPEQ apply_sign
|
|
GOTO stack_unwind
|
|
|
|
cant_substract:
|
|
// pop a - (k * b) from the stack
|
|
POP
|
|
|
|
ILOAD k
|
|
BIPUSH 1
|
|
IF_ICMPEQ apply_sign
|
|
GOTO stack_unwind
|
|
|
|
apply_sign:
|
|
ILOAD signed
|
|
IFEQ ret_res
|
|
BIPUSH 0
|
|
ILOAD res
|
|
ISUB
|
|
IRETURN
|
|
ret_res:
|
|
ILOAD res
|
|
IRETURN
|
|
|
|
negate_a:
|
|
BIPUSH 0
|
|
ILOAD a
|
|
ISUB
|
|
ISTORE a
|
|
IINC signed 1
|
|
GOTO hb
|
|
negate_b:
|
|
BIPUSH 0
|
|
ILOAD b
|
|
ISUB
|
|
ISTORE b
|
|
IINC signed 1
|
|
GOTO handled
|
|
|
|
division_by_zero:
|
|
BIPUSH 100
|
|
OUT
|
|
BIPUSH 105
|
|
OUT
|
|
BIPUSH 118
|
|
OUT
|
|
BIPUSH 32
|
|
OUT
|
|
BIPUSH 98
|
|
OUT
|
|
BIPUSH 121
|
|
OUT
|
|
BIPUSH 32
|
|
OUT
|
|
BIPUSH 48
|
|
OUT
|
|
BIPUSH 10
|
|
OUT
|
|
ERR
|
|
.end-method
|
|
|
|
.method divby2pow(x, y)
|
|
.var
|
|
s
|
|
b
|
|
r
|
|
top_bit
|
|
.end-var
|
|
|
|
ILOAD x
|
|
IFLT set_sign
|
|
BIPUSH 1
|
|
ISTORE s
|
|
calculation:
|
|
BIPUSH 1
|
|
ISTORE b
|
|
BIPUSH 0
|
|
ISTORE r
|
|
LDC_W _OBJREF
|
|
ILOAD x
|
|
INVOKEVIRTUAL msb
|
|
ISTORE top_bit
|
|
|
|
GOTO loop_body
|
|
|
|
loop_update:
|
|
ILOAD y
|
|
DUP
|
|
IADD
|
|
ISTORE y
|
|
ILOAD b
|
|
DUP
|
|
IADD
|
|
ISTORE b
|
|
loop_body:
|
|
ILOAD x
|
|
ILOAD y
|
|
IAND
|
|
IFEQ second_if
|
|
ILOAD r
|
|
ILOAD b
|
|
IOR
|
|
ISTORE r
|
|
second_if:
|
|
ILOAD y
|
|
ILOAD top_bit
|
|
ISUB
|
|
IFLT loop_update
|
|
|
|
handle_sign:
|
|
ILOAD s
|
|
IFEQ ret_neg_r
|
|
ILOAD r
|
|
IRETURN
|
|
|
|
ret_neg_r:
|
|
BIPUSH 0
|
|
ILOAD r
|
|
ISUB
|
|
IRETURN
|
|
|
|
set_sign:
|
|
BIPUSH 0
|
|
ISTORE s
|
|
BIPUSH 0
|
|
ILOAD x
|
|
ISUB
|
|
ISTORE x
|
|
GOTO calculation
|
|
.end-method
|
|
|
|
.method mandelbrot(real0, imag0)
|
|
.var
|
|
real
|
|
imag
|
|
realq
|
|
imagq
|
|
n
|
|
.end-var
|
|
|
|
BIPUSH 0
|
|
ISTORE n
|
|
ILOAD real0
|
|
ISTORE real
|
|
ILOAD imag0
|
|
ISTORE imag
|
|
GOTO for_loop
|
|
|
|
for_update:
|
|
IINC n 1
|
|
ILOAD n
|
|
LDC_W MAX_ITERATIONS
|
|
IF_ICMPEQ for_done
|
|
|
|
for_loop:
|
|
LDC_W _OBJREF
|
|
LDC_W _OBJREF
|
|
ILOAD real
|
|
ILOAD real
|
|
INVOKEVIRTUAL mul
|
|
LDC_W MULTIPLIER
|
|
INVOKEVIRTUAL divby2pow
|
|
ISTORE realq
|
|
LDC_W _OBJREF
|
|
LDC_W _OBJREF
|
|
ILOAD imag
|
|
ILOAD imag
|
|
INVOKEVIRTUAL mul
|
|
LDC_W MULTIPLIER
|
|
INVOKEVIRTUAL divby2pow
|
|
ISTORE imagq
|
|
|
|
ILOAD realq
|
|
ILOAD imagq
|
|
IADD
|
|
LDC_W INV_FFF
|
|
IAND
|
|
IFEQ if_not_part
|
|
GOTO premature_exit
|
|
|
|
if_not_part:
|
|
ILOAD imag0
|
|
LDC_W _OBJREF
|
|
LDC_W _OBJREF
|
|
ILOAD real
|
|
ILOAD imag
|
|
INVOKEVIRTUAL mul
|
|
LDC_W MULTIPLIERDIV2
|
|
INVOKEVIRTUAL divby2pow
|
|
IADD
|
|
ISTORE imag
|
|
|
|
ILOAD realq
|
|
ILOAD imagq
|
|
ISUB
|
|
ILOAD real0
|
|
IADD
|
|
ISTORE real
|
|
GOTO for_update
|
|
|
|
for_done:
|
|
LDC_W MAX_ITERATIONS
|
|
IRETURN
|
|
|
|
premature_exit:
|
|
ILOAD n
|
|
IRETURN
|
|
.end-method
|
|
|
|
.method mandelbrot_print(x, y)
|
|
.var
|
|
value
|
|
.end-var
|
|
|
|
LDC_W _OBJREF
|
|
ILOAD x
|
|
ILOAD y
|
|
INVOKEVIRTUAL mandelbrot
|
|
ISTORE value
|
|
|
|
// Palet " `':tfLCG08@"
|
|
ILOAD value
|
|
BIPUSH 8
|
|
ISUB
|
|
IFLT print_space
|
|
ILOAD value
|
|
BIPUSH 10
|
|
ISUB
|
|
IFLT print_backtick
|
|
ILOAD value
|
|
BIPUSH 12
|
|
ISUB
|
|
IFLT print_quote
|
|
ILOAD value
|
|
BIPUSH 14
|
|
ISUB
|
|
IFLT print_colon
|
|
ILOAD value
|
|
BIPUSH 16
|
|
ISUB
|
|
IFLT print_t
|
|
ILOAD value
|
|
BIPUSH 18
|
|
ISUB
|
|
IFLT print_f
|
|
ILOAD value
|
|
BIPUSH 20
|
|
ISUB
|
|
IFLT print_L
|
|
ILOAD value
|
|
BIPUSH 22
|
|
ISUB
|
|
IFLT print_C
|
|
ILOAD value
|
|
BIPUSH 24
|
|
ISUB
|
|
IFLT print_G
|
|
ILOAD value
|
|
BIPUSH 26
|
|
ISUB
|
|
IFLT print_0
|
|
ILOAD value
|
|
BIPUSH 28
|
|
ISUB
|
|
IFLT print_8
|
|
print_at:
|
|
BIPUSH 64
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_space:
|
|
BIPUSH 32
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_backtick:
|
|
BIPUSH 96
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_quote:
|
|
BIPUSH 39
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_colon:
|
|
BIPUSH 58
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_t:
|
|
BIPUSH 116
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_f:
|
|
BIPUSH 102
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_L:
|
|
BIPUSH 76
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_C:
|
|
BIPUSH 67
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_G:
|
|
BIPUSH 71
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_0:
|
|
BIPUSH 48
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
print_8:
|
|
BIPUSH 56
|
|
OUT
|
|
BIPUSH 0
|
|
IRETURN
|
|
|
|
.end-method
|
|
|
|
.method msb(x)
|
|
lbffffffff: ILOAD x
|
|
LDC_W BFFFF0000
|
|
IAND
|
|
IFEQ lb0000ffff
|
|
lbffff0000: ILOAD x
|
|
LDC_W BFF000000
|
|
IAND
|
|
IFEQ lb00ff0000
|
|
lbff000000: ILOAD x
|
|
LDC_W BF0000000
|
|
IAND
|
|
IFEQ lb0f000000
|
|
lbf0000000: ILOAD x
|
|
LDC_W BC0000000
|
|
IAND
|
|
IFEQ lb30000000
|
|
lbc0000000: ILOAD x
|
|
LDC_W B80000000
|
|
IAND
|
|
IFEQ lb40000000
|
|
lb80000000: LDC_W B80000000
|
|
IRETURN
|
|
lb40000000: LDC_W B40000000
|
|
IRETURN
|
|
lb30000000: ILOAD x
|
|
LDC_W B20000000
|
|
IAND
|
|
IFEQ lb10000000
|
|
lb20000000: LDC_W B20000000
|
|
IRETURN
|
|
lb10000000: LDC_W B10000000
|
|
IRETURN
|
|
lb0f000000: ILOAD x
|
|
LDC_W B0C000000
|
|
IAND
|
|
IFEQ lb03000000
|
|
lb0c000000: ILOAD x
|
|
LDC_W B08000000
|
|
IAND
|
|
IFEQ lb04000000
|
|
lb08000000: LDC_W B08000000
|
|
IRETURN
|
|
lb04000000: LDC_W B04000000
|
|
IRETURN
|
|
lb03000000: ILOAD x
|
|
LDC_W B02000000
|
|
IAND
|
|
IFEQ lb01000000
|
|
lb02000000: LDC_W B02000000
|
|
IRETURN
|
|
lb01000000: LDC_W B01000000
|
|
IRETURN
|
|
lb00ff0000: ILOAD x
|
|
LDC_W B00F00000
|
|
IAND
|
|
IFEQ lb000f0000
|
|
lb00f00000: ILOAD x
|
|
LDC_W B00C00000
|
|
IAND
|
|
IFEQ lb00300000
|
|
lb00c00000: ILOAD x
|
|
LDC_W B00800000
|
|
IAND
|
|
IFEQ lb00400000
|
|
lb00800000: LDC_W B00800000
|
|
IRETURN
|
|
lb00400000: LDC_W B00400000
|
|
IRETURN
|
|
lb00300000: ILOAD x
|
|
LDC_W B00200000
|
|
IAND
|
|
IFEQ lb00100000
|
|
lb00200000: LDC_W B00200000
|
|
IRETURN
|
|
lb00100000: LDC_W B00100000
|
|
IRETURN
|
|
lb000f0000: ILOAD x
|
|
LDC_W B000C0000
|
|
IAND
|
|
IFEQ lb00030000
|
|
lb000c0000: ILOAD x
|
|
LDC_W B00080000
|
|
IAND
|
|
IFEQ lb00040000
|
|
lb00080000: LDC_W B00080000
|
|
IRETURN
|
|
lb00040000: LDC_W B00040000
|
|
IRETURN
|
|
lb00030000: ILOAD x
|
|
LDC_W B00020000
|
|
IAND
|
|
IFEQ lb00010000
|
|
lb00020000: LDC_W B00020000
|
|
IRETURN
|
|
lb00010000: LDC_W B00010000
|
|
IRETURN
|
|
lb0000ffff: ILOAD x
|
|
LDC_W B0000FF00
|
|
IAND
|
|
IFEQ lb000000ff
|
|
lb0000ff00: ILOAD x
|
|
LDC_W B0000F000
|
|
IAND
|
|
IFEQ lb00000f00
|
|
lb0000f000: ILOAD x
|
|
LDC_W B0000C000
|
|
IAND
|
|
IFEQ lb00003000
|
|
lb0000c000: ILOAD x
|
|
LDC_W B00008000
|
|
IAND
|
|
IFEQ lb00004000
|
|
lb00008000: LDC_W B00008000
|
|
IRETURN
|
|
lb00004000: LDC_W B00004000
|
|
IRETURN
|
|
lb00003000: ILOAD x
|
|
LDC_W B00002000
|
|
IAND
|
|
IFEQ lb00001000
|
|
lb00002000: LDC_W B00002000
|
|
IRETURN
|
|
lb00001000: LDC_W B00001000
|
|
IRETURN
|
|
lb00000f00: ILOAD x
|
|
LDC_W B00000C00
|
|
IAND
|
|
IFEQ lb00000300
|
|
lb00000c00: ILOAD x
|
|
LDC_W B00000800
|
|
IAND
|
|
IFEQ lb00000400
|
|
lb00000800: LDC_W B00000800
|
|
IRETURN
|
|
lb00000400: LDC_W B00000400
|
|
IRETURN
|
|
lb00000300: ILOAD x
|
|
LDC_W B00000200
|
|
IAND
|
|
IFEQ lb00000100
|
|
lb00000200: LDC_W B00000200
|
|
IRETURN
|
|
lb00000100: LDC_W B00000100
|
|
IRETURN
|
|
lb000000ff: ILOAD x
|
|
LDC_W B000000F0
|
|
IAND
|
|
IFEQ lb0000000f
|
|
lb000000f0: ILOAD x
|
|
LDC_W B000000C0
|
|
IAND
|
|
IFEQ lb00000030
|
|
lb000000c0: ILOAD x
|
|
LDC_W B00000080
|
|
IAND
|
|
IFEQ lb00000040
|
|
lb00000080: LDC_W B00000080
|
|
IRETURN
|
|
lb00000040: BIPUSH 64
|
|
IRETURN
|
|
lb00000030: ILOAD x
|
|
LDC_W B00000020
|
|
IAND
|
|
IFEQ lb00000010
|
|
lb00000020: BIPUSH 32
|
|
IRETURN
|
|
lb00000010: BIPUSH 16
|
|
IRETURN
|
|
lb0000000f: ILOAD x
|
|
LDC_W B0000000C
|
|
IAND
|
|
IFEQ lb00000003
|
|
lb0000000c: ILOAD x
|
|
LDC_W B00000008
|
|
IAND
|
|
IFEQ lb00000004
|
|
lb00000008: BIPUSH 8
|
|
IRETURN
|
|
lb00000004: BIPUSH 4
|
|
IRETURN
|
|
lb00000003: ILOAD x
|
|
LDC_W B00000002
|
|
IAND
|
|
IFEQ lb00000001
|
|
lb00000002: BIPUSH 2
|
|
IRETURN
|
|
lb00000001: ILOAD x
|
|
IFEQ lb00000000
|
|
BIPUSH 1
|
|
IRETURN
|
|
lb00000000: BIPUSH 0
|
|
IRETURN
|
|
.end-method
|
|
|
|
.method mul(a, b)
|
|
.var
|
|
signed
|
|
res
|
|
pow2
|
|
sum
|
|
.end-var
|
|
|
|
// store the signed state
|
|
ILOAD a
|
|
LDC_W BITMASK_SIGNBIT
|
|
IAND
|
|
ILOAD b
|
|
LDC_W BITMASK_SIGNBIT
|
|
IAND
|
|
IADD
|
|
ISTORE signed
|
|
|
|
// get absolute of a and b
|
|
hsa: ILOAD a
|
|
IFLT negate_a
|
|
hsb: ILOAD b
|
|
IFLT negate_b
|
|
|
|
for_init:
|
|
BIPUSH 0
|
|
ISTORE res // result
|
|
BIPUSH 1
|
|
ISTORE pow2 // 2^n
|
|
ILOAD b
|
|
ISTORE sum // b * 2^n
|
|
|
|
for_loop:
|
|
// if (a < (1 << n)) -> done
|
|
ILOAD a
|
|
ILOAD pow2
|
|
ISUB
|
|
IFLT apply_sign
|
|
|
|
// if (a & (1 << n) == 0) continue
|
|
ILOAD a
|
|
ILOAD pow2
|
|
IAND
|
|
IFEQ for_update
|
|
|
|
// res += b * 2^n
|
|
ILOAD res
|
|
ILOAD sum
|
|
IADD
|
|
ISTORE res
|
|
|
|
for_update:
|
|
ILOAD pow2
|
|
DUP
|
|
IADD
|
|
ISTORE pow2
|
|
ILOAD sum
|
|
DUP
|
|
IADD
|
|
ISTORE sum
|
|
GOTO for_loop
|
|
|
|
negate_a:
|
|
BIPUSH 0
|
|
ILOAD a
|
|
ISUB
|
|
ISTORE a
|
|
GOTO hsb
|
|
negate_b:
|
|
BIPUSH 0
|
|
ILOAD b
|
|
ISUB
|
|
ISTORE b
|
|
GOTO for_init
|
|
|
|
apply_sign:
|
|
// res possibly overflowed, apply positive filter
|
|
ILOAD res
|
|
LDC_W BITMASK_INVSIGN
|
|
IAND
|
|
ILOAD signed
|
|
IFEQ ret_res
|
|
BIPUSH 0
|
|
SWAP
|
|
ISUB
|
|
IRETURN
|
|
|
|
ret_res:
|
|
IRETURN
|
|
.end-method
|
|
|