File: //usr/local/ssl/lib/bcc/rules.86
# Rules for optimizing BCC assembler output
# Rules for loading short variables
mov %2,%[ax|bx|cx|dx]1
mov %[ax|bx|cx|dx]1,%2
=
mov %2,%1
# Assign a constant
mov %[ax|bx|cx|dx]3,%[#|*]0%1
mov %2[%4],%[ax|bx|cx|dx]3
!BCC_EOS
=
mov word ptr %2[%4],%0%1
!BCC_EOS
# Assign a constant char
mov al,%[#|*]0%1
mov %2,al
!BCC_EOS
=
mov byte ptr %2,%0%1
!BCC_EOS
# Assign a constant long from a small int
xor ax,ax
mov bx,%[#|*]0%1
mov [%2],ax
mov [%2+2],bx
!BCC_EOS
=
mov word ptr [%2],#0
mov word ptr [%2+2],%0%1
!BCC_EOS
# Assign a constant long from a 2^16 mod int.
mov ax,%[#|*]0%1
xor bx,bx
mov [%2],ax
mov [%2+2],bx
!BCC_EOS
=
mov word ptr [%2],%0%1
mov word ptr [%2+2],#0
!BCC_EOS
# Assign a constant long from a big int
mov ax,%[#|*]4%1
mov bx,%[#|*]5%3
mov [%2],ax
mov [%2+2],bx
!BCC_EOS
=
mov word ptr [%2],%4%1
mov word ptr [%2+2],%5%3
!BCC_EOS
# rule for (char*) *x++
mov bx,%1
%[inc|dec]2 bx
mov %1,bx
mov al,-1[bx]
xor ah,ah
=
mov bx,%1
%2 word ptr %1
mov al,[bx]
xor ah,ah
# Rules for incrementing short variables
mov %[ax|bx|si|di]2,%1
%[inc|dec]3 %[ax|bx|si|di]2
mov %1,%[ax|bx|si|di]2
!BCC_EOS
=
%3 word ptr %1
!BCC_EOS
mov %[ax|bx|si|di]2,%1
%[inc|dec]3 %[ax|bx|si|di]2
mov %1,%[ax|bx|si|di]2
=
%3 word ptr %1
mov %2,%1
# Rules for manipulating characters with register char*s
inc %[si|di]*
inc %[si|di]*
mov al,-1[si]
mov -1[di],al
!BCC_EOS
=
lodsb
stosb
!BCC_EOS
inc %[si|di]*
inc %[si|di]*
mov al,-1[di]
mov -1[si],al
!BCC_EOS
=
xchg si,di
lodsb
stosb
xchg si,di
!BCC_EOS
inc si
mov al,-1[si]
=
lodsb
inc di
mov -1[di],al
=
stosb
dec %[si|di]*
dec %[si|di]*
mov al,1[si]
mov 1[di],al
=
std
lodsb
stosb
cld
dec %[si|di]*
dec %[si|di]*
mov al,1[di]
mov 1[si],al
=
std
xchg si,di
lodsb
stosb
xchg si,di
cld
dec si
mov al,1[si]
=
std
lodsb
cld
dec di
mov 1[di],al
=
std
stosb
cld
# Rules for manipulating short values
# These rules only apply at end of statment.
mov %[ax|bx]2,%1
%[add|and|xor|sub|or]4 %[ax|bx]2,%3
mov %1,%[ax|bx]2
!BCC_EOS
=
mov %2,%3
%4 %1,%2
!BCC_EOS
mov %[ax|bx]2,%1
%[add|and|xor|or]4 %[ax|bx]2,%3
mov %3,%[ax|bx]2
!BCC_EOS
=
mov %2,%1
%4 %3,%2
!BCC_EOS
mov al,%1
xor ah,ah
%[add|and|xor|sub|or]2 ax,%[#|*]0%3
mov %1,al
!BCC_EOS
=
%2 byte ptr %1,%0%3
!BCC_EOS
# This is safe with an embedded assign.
mov %[ax|bx]4,%1
%[add|and|xor|sub|or]2 %[si|di]3,%[ax|bx]4
=
%2 %3,%1
# Rules for comparing short values
# Compare doesn't need to leave any register in a specific state.
mov %[ax|bx]3,%1[%4]
cmp %[ax|bx]3,%[#|*]0%2
=
cmp word ptr %1[%4],%0%2
mov al,%1[%4]
cmp al,%[#|*]0%2
=
cmp byte ptr %1[%4],%0%2
mov %[ax|bx]3,%[ax|bx|cx|dx|si|di]2
cmp %[ax|bx]3,%1
=
cmp %2,%1
# General comparison rules
xor %1,%1
mov %2,%3
cmp %2,%1
=
mov %2,%3
cmp %2,#0
mov %1,%[#|*]0%2
mov %3,%4
cmp %3,%1
=
mov %3,%4
cmp %3,%0%2
mov %1,%2
cmp %1,%[#|*]00
%[jne |je ]4 %3
=
mov %1,%2
test %1,%1
%4 %3
%[and|xor|or]1 %2,%3
test %2,%2
=
%1 %2,%3
# General incrementation and decrementation rules
inc %3 ptr %1
mov %2,%1
dec %2
=
mov %2,%1
inc %3 ptr %1
dec %3 ptr %1
mov %2,%1
inc %2
=
mov %2,%1
dec %3 ptr %1
mov %1,%2
inc %3 ptr %2
push %1
=
push %3 ptr %2
inc %3 ptr %2
mov %1,%2
dec %3 ptr %2
push %1
=
push %3 ptr %2
dec %3 ptr %2
# Misc. rules
push word %[#|*]0%1
inc %[si|di]2
inc %[si|di]2
mov %[ax|bx|cx|dx]3,%*[bp]
mov %4[%[si|di]2],%[ax|bx|cx|dx]3
inc sp
inc sp
=
mov word ptr %(%4+2)[%2],%0%1
inc %2
inc %2
push %1
mov %[ax|bx|cx|dx]3,%2
%[add|and|xor|or]4 %[ax|bx|cx|dx]3,%*[bp]
inc sp
inc sp
=
mov %3,%1
%4 %3,%2
# If %1 is ax this fails badly.
# push %1
# mov %[ax|bx|cx|dx]3,%2
# %[add|sub|and|xor|or]5 %[ax|bx|cx|dx]3,%6
# %[add|sub|and|xor|or]4 %[ax|dx|cx|dx]3,%*[bp]
# inc sp
# inc sp
# =
# mov %3,%2
# %5 %3,%6
# %4 %3,%1
push %1
mov %[ax|bx|cx|dx]3,%*[bp]
%[add|sub|and|xor|or]4 %2,%[ax|bx|cx|dx]3
inc sp
inc sp
=
mov %3,%1
%4 %2,%3
mov %1,%[ax|bx|cx|dx]2
push %1
=
mov %1,%2
push %2
# Rules to remove superflous mov instructions
mov %1,%2
mov %1,%2
=
mov %1,%2
mov %1,%2
.%3:
mov %1,%2
=
.%3:
mov %1,%2
mov %1,%2
mov %2,%1
=
mov %1,%2
mov %1,%[ax|bx|cx|dx|eax|ebx|ecx|edx]2
mov %[ax|bx|cx|dx|eax|ebx|ecx|edx]3,%1
=
mov %1,%2
mov %3,%2
mov %1,%1
=
!mov %1,%1
# Sometimes the compiler puts a jump right after a ret or another jump
# (in if-else-if constructions). Eliminate the second unnecessary jump.
# Also it puts a jump to the next instruction in extensive if-else
# constructions. That jump can also be removed.
jmp .%1
jmp .%2
=
jmp %1
ret
jmp %2
=
ret
jmp .%1
.%1:
=
.%1:
jmp .%1
.%2:
!BCC_EOS
.%1:
=
.%2:
!BCC_EOS
.%1:
jmp .%1
.%3:
.%2:
.%1:
=
.%3:
.%2:
.%1:
# When using register variables the compiler initializes them when
# they are found in the source code, and sets up the stack frame for
# other local variables lateron. Move initialization of register variables
# behind the add-sp instruction to make further optimization easier.
proc_start
mov %[si|di]3,%1
add sp,*%2
=
proc_start
add sp,*%2
mov %3,%1
proc_start
mov %[si|di]3,%1
dec sp
dec sp
=
proc_start
dec sp
dec sp
mov %3,%1
add sp,*%1
add sp,*%2
=
add sp,*%1+%2
dec sp
dec sp
add sp,*%1
=
add sp,*%1-2
add sp,*%1
dec sp
dec sp
=
add sp,*%1-2
inc sp
inc sp
%1 %2
inc sp
inc sp
=
%1 %2
add sp,*4
inc sp
inc sp
%1 %2
add sp,*%3
=
%1 %2
add sp,*%3+2
add sp,*%3
%1 %2
inc sp
inc sp
=
%1 %2
add sp,*%3+2
add sp,*%3
%1 %2
add sp,*%4
=
%1 %2
add sp,*%3+%4
# And a great bug floating push/pop
push dx
push cx
push bx
push ax
pop ax
pop bx
pop cx
pop dx
=
! push/pop float
# Long right shift by 16 unsigned
mov ax,%1
mov bx,%2
xchg bx,ax
xor bx,bx
=
mov ax,%2
xor bx,bx
# Long right shift by 16 signed
mov ax,%1
mov bx,%2
xchg bx,ax
cwd
=
mov ax,%2
cwd
# Load long and exchange
mov ax,%1
mov bx,%2
xchg bx,ax
=
mov bx,%1
mov ax,%2
# Repeated clear.
xor bx,bx
xchg bx,ax
xor ax,ax
=
xchg bx,ax
xor ax,ax
# Long expression assigned to an int
cwd
mov bx,dx
mov %1,ax
!BCC_EOS
=
mov %1,ax
!BCC_EOS
# Load unsigned into high word of long
mov ax,%1
xchg bx,ax
xor ax,ax
=
mov bx,%1
xor ax,ax
# Souped up strcpy; "while(*d++ = *s++);" in a function with no reg vars.
.%3:
!BCC_EOS
.%4:
mov bx,%1
inc bx
mov %1,bx
mov si,%2
inc si
mov %2,si
mov al,-1[bx]
mov -1[si],al
test al,al
jne .%3
=
.%4:
mov si,%1
mov di,%2
.%3:
lodsb
stosb
test al,al
jne .%3
mov %1,si
mov %2,di
!BCC_EOS
###
mov ax,%1
mov %[ax|bx|cx|dx]2,ax
mov ax,%3
=
mov %2,%1
mov ax,%3