#
# 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.gcc,v 1.6 2007/01/06 18:31:20 gkminix Exp $
#
#####################################################################
#
# GCC produces code which uses EAX, EBX, ECX, EDX and ESP as index
# registers in addition to the standard index registers. It also uses
# the LEA instruction together with these registers to implement add
# and shift operations. These only work with 32-bit addressing, We
# have therefore to add the ADDR32 prefix to all those instructions
# when running in a .CODE16 segment.
#
# 1.) Operations from memory into register
#
# Base without index
?0	?1(%e?[ax|cx|dx|sp]2),?5
=
addr32 ?0	?1(%e?2),?5

?![leal|addr32 leal]0	?1(%e?[si|di|bx|bp]2),?5
=
?0	?1(%?2),?5

leal	?1(%e?[si|di|bx|bp]2),?5
=
addr32 leal	?1(%e?2),?5


# Base with index
?0	?1(%e?[ax|cx|dx|si|di|sp]2,%e?[ax|bx|cx|dx|si|di|bp]3),?5
=
addr32 ?0	?1(%e?2,%e?3),?5

?0	?1(%e?[bx|bp]2,%e?[ax|bx|cx|dx]3),?5
=
addr32 ?0	?1(%e?2,%e?3),?5

?![leal|addr32 leal]0	?1(%e?[bx|bp]6,%e?[si|di]2),?5
=
?0	?1(%?6,%?2),?5

leal	?1(%e?[bx|bp]6,%e?[si|di]2),?5
=
addr32 leal	?1(%e?6,%e?2),?5


# Base with scaled index
?0	?1(%e?[ax|bx|cx|dx|si|di|sp|bp]2,%e?[ax|bx|cx|dx|si|di|bp]3,?4),?5
=
addr32 ?0	?1(%e?2,%e?3,?4),?5


# Scaled index without base
?0	?1(,%e?[ax|bx|cx|dx|si|di|bp]3,?4),?5
=
addr32 ?0	?1(,%e?3,?4),?5



#
# 2.) Operations from register into memory or within memory
#     These rules match
#			incl (%eax)
#     as well as
#			movl %ebx,(%eax)
#
# Base without index
?0	?1(%e?[ax|cx|dx|sp]2)
=
addr32 ?0	?1(%e?2)

?0	?1(%e?[si|di|bx|bp]2)
=
?0	?1(%?2)


# Base with index
?0	?1(%e?[ax|cx|dx|si|di|sp]2,%e?[ax|bx|cx|dx|si|di|bp]3)
=
addr32 ?0	?1(%e?2,%e?3)

?0	?1(%e?[bx|bp]6,%e?[si|di]2)
=
?0	?1(%?6,%?2)

?0	?1(%e?[bx|bp]6,%e?[ax|bx|cx|dx]2)
=
addr32 ?0	?1(%e?6,%e?2)


# Base with scaled index
?0	?1(%e?[ax|bx|cx|dx|si|di|sp|bp]2,%e?[ax|bx|cx|dx|si|di|bp]3,?4)
=
addr32 ?0	?1(%e?2,%e?3,?4)


# Scaled index without base
?0	?1(,%e?[ax|bx|cx|dx|si|di|bp]3,?4)
=
addr32 ?0	?1(,%e?3,?4)



#
#####################################################################
#
# Handle indexed jumps and calls
#
?[jmp|call]0	*%e?[ax|bx|cx|dx|si|di]1
=
?0	*%?1



#
#####################################################################
#
# Remove the .ident opcode which GCC produces
#
.ident	\"?1\"
=
/* .ident \"?1\" */

