X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fseabios%2Fscripts%2Fvgafixup.py;fp=qemu%2Froms%2Fseabios%2Fscripts%2Fvgafixup.py;h=2053cd5d78e5935658e1fecec074b258ba1d75ba;hb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;hp=0000000000000000000000000000000000000000;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/qemu/roms/seabios/scripts/vgafixup.py b/qemu/roms/seabios/scripts/vgafixup.py new file mode 100644 index 000000000..2053cd5d7 --- /dev/null +++ b/qemu/roms/seabios/scripts/vgafixup.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# Work around x86emu bugs by replacing problematic instructions. +# +# Copyright (C) 2012 Kevin O'Connor +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +# The x86emu code widely used in Linux distributions when running Xorg +# in vesamode is known to have issues with "retl", "leavel", "entryl", +# "leal", and some variants of "calll". This code modifies those +# instructions that are known to be generated by gcc to avoid +# triggering the x86emu bugs. + +# It is also known that the Windows vgabios emulator has issues with +# addressing negative offsets to the %esp register. That has been +# worked around by not using the gcc parameter "-fomit-frame-pointer" +# when compiling. + +import sys, re + +# leal parameter regex - example string: -3(%edx,%eax,8), %eax +re_leal = re.compile( + r'^\s*(?P[^(]*?)\s*' + r'\(\s*(?P[^,)]*?)\s*(?:,\s*(?P[^,)]*?)\s*)?' + r'(?:,\s*(?P[^,)]*?)\s*)?\)\s*' + r',\s*(?P.*?)\s*$') + +# Find an alternate set of instructions for a given "leal" instruction +def handle_leal(sline): + m = re_leal.match(sline[5:]) + if m is None or m.group('index') == '%esp': + print("Unable to fixup leal instruction: %s" % (sline,)) + sys.exit(-1) + offset, base, index, scale, dest = m.group( + 'offset', 'base', 'index', 'scale', 'dest') + if dest == '%esp': + # If destination is %esp then just use 16bit leaw instead + return 'leaw %s\n' % (sline[5:].replace('%e', '%'),) + if not scale: + scale = '1' + scale = {1: 0, 2: 1, 4: 2, 8: 3}[int(scale, 0)] + # Try to rearrange arguments to simplify 'base' (to improve code gen) + if not scale and base == index: + base, index, scale = '', index, 1 + elif not index or (not scale and base in (dest, '%esp') and index != dest): + base, index, scale = index, base, 0 + # Produce instructions to calculate "leal" + insns = ['pushfw'] + if base != dest: + # Calculate "leal" directly in dest register + if index != dest: + insns.insert(0, 'movl %s, %s' % (index, dest)) + if scale: + insns.append('shll $%d, %s' % (scale, dest)) + if base: + if base == '%esp': + offset += '+2' + insns.append('addl %s, %s' % (base, dest)) + elif base == index: + # Use "imull" method + insns.append('imull $%d, %s' % ((1< %s\n %s" % (sline, out[-1].strip())) + else: + out.append(line) + infile.close() + outfile = open(outfilename, 'w') + outfile.write(''.join(out)) + outfile.close() + +if __name__ == '__main__': + main()