#
# gccopt rules to convert gcc assembler output to real mode
#
# Copyright (C) 2003-2007 Gero Kuhlmann <gero@gkminix.han.de>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: rules.post,v 1.7 2007/01/06 18:31:20 gkminix Exp $
#
#####################################################################
#
# Remove all .align statements. They may speed up execution but give
# much bigger code.
#
.align	?1
.align	?1
=
.align	?1

.align	?1
=
/* .align ?1 */



#
#####################################################################
#
# Make all indexed jumps and calls with 16-bit jump tables
#
addr32 ?[jmp|call]1	*.L?2(,%e?[ax|bx|cx|dx|si|di]3,4)
=
addr32 ?1	*.L?2(,%e?3,2)

.long	.L?(|1|)1
=
.word	.L?1



#
#####################################################################
#
# Remove double moves generated by other optimizations
#
mov?[z|s]0?[w|b]1l	%?[a|b|c|d]2?[l|x]3,%e?2x
mov?0?1l	%?2?3,%e?2x
=
mov?0?1l	%?2?3,%e?2x

mov?[l|w|b]0	?1,?1
=
/*mov?0	?1,?1*/



#
#####################################################################
#
# Misc. rules
#


# First load a word register, and then add something using LEAL. In
# this case we assume that the destination register is intented to
# be a word register as well.
mov?0w	?1,%?[si|di|bx]2
addr32 leal	?3(%e?2),%e?4
=
mov?0w	?1,%?2
leaw	?3(%?2),%?4


# Load an indexed value using BX and DI or SI
movzwl	%bx,%e?3
addr32 mov?[s|z]0?[b|w]1l	(%e?3,%e?[si|di]2),%e?3
=
mov?0?1l	(%bx,%?2),%e?3


# Move a byte value into a general register, and than add something
# to AL. In this case, we assume that the size of the operation is
# intended to be byte-wise.
movb	%al,%?[b|c|d]0l
addr32 leal	?1(%e?0x),%eax
=
movb	%al,%?0l
addb	$?1,%al

?[movb|addr32 movb]4	?0,%?[a|b|c|d]1l
?[add|sub]2l	$?3,%e?1x
=
?4	?0,%?1l
?2b	$?3,%?1l


# Add two long registers
addr32 leal	(%e?[ax|bx|cx|dx|si|di]1,%e?[ax|bx|cx|dx|si|di]2),%e?1
=
addl	%e?2,%e?1


# Move the same value first into a register and then into a variable
movl	?1,%e?[ax|bx|cx|dx|si|di]2
movl	?1,?3
=
movl	?1,%e?2
movl	%e?2,?3

movl	?1,%e?[ax|bx|cx|dx|si|di]2
mov?[w|zwl]4	?1,?3
=
movl	?1,%e?2
mov?4	%?2,?3

movl	?1,%e?[a|b|c|d]2x
mov?[b|zbw|zbl]4	?1,?3
=
movl	?1,%e?2x
mov?4	%?2l,?3


# Move zero into a register/variable following a conditional jump
testl	%e?[ax|bx|cx|dx]1,%e?1
jne	?2
movl	$0,?3
=
testl	%e?1,%e?1
jne	?2
movl	%e?1,?3

testl	%e?[ax|bx|cx|dx]1,%e?1
jne	?2
movw	$0,?3
=
testl	%e?1,%e?1
jne	?2
movw	%?1,?3

