The majority of gcc generated leal instructions don't require a full out-of-line function call. Detect common cases where the calculation can be performed inline.
Signed-off-by: Kevin O'Connor kevin@koconnor.net ---
This version is a bit easier to read and is safer in some corner cases.
--- scripts/vgafixup.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/scripts/vgafixup.py b/scripts/vgafixup.py index e144382..9faea0b 100644 --- a/scripts/vgafixup.py +++ b/scripts/vgafixup.py @@ -25,6 +25,21 @@ re_leal = re.compile( r'(?:,\s*(?P<scale>[^,)]*?)\s*)?)\s*' r',\s*(?P<dest>.*?)\s*$')
+# Produce instructions to calculate "leal" directly in dest register +def handle_leal_inline(offset, base, index, scale, dest): + out = [] + if index != dest: + out.append('movl %s, %s' % (index, dest)) + out.append('pushfl') + if scale: + out.append('shll $%d, %s' % (scale, dest)) + if offset: + out.append('addl $%d, %s' % (offset, dest)) + if base != '$0': + out.append('addl %s, %s' % (base, dest)) + out.append('popfl\n') + return ' ; '.join(out) + # Find an alternate set of instructions for a given "leal" instruction def handle_leal(sline): m = re_leal.match(sline[5:]) @@ -33,16 +48,27 @@ def handle_leal(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 offset: offset = '0' + offset = int(offset, 0) if not base: base = '$0' - if not index: - index = '$0' if not scale: scale = '1' scale = {'1': 0, '2': 1, '4': 2, '8': 3}[scale] - return ('pushl %s ; pushl %s ; pushl $%s ; pushw $%d' + if not index: + return handle_leal_inline(offset, '$0', base, 0, dest) + if base != dest and base != '%esp': + return handle_leal_inline(offset, base, index, scale, dest) + if not scale and index != dest and index != '%esp': + return handle_leal_inline(offset, index, base, 0, dest) + if not scale and index == base: + return handle_leal_inline(offset, '$0', index, 1, dest) + # Use default out-of-line calculation + return ('pushl %s ; pushl %s ; pushl $%d ; pushw $%d' ' ; callw emulate_leal ; popl %s\n' % ( base, index, offset, scale, dest))
@@ -60,6 +86,7 @@ def main(): out.append('pushw %ax ; callw' + sline[4:] + '\n') elif sline.startswith('leal'): out.append(handle_leal(sline)) + #print "-> %s\n %s" % (sline, out[-1].strip()) else: out.append(line) infile.close()