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 --- scripts/vgafixup.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/scripts/vgafixup.py b/scripts/vgafixup.py index e144382..cee5842 100644 --- a/scripts/vgafixup.py +++ b/scripts/vgafixup.py @@ -33,8 +33,12 @@ 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: @@ -42,7 +46,28 @@ def handle_leal(sline): 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 scale and (index == '$0' or base == dest or base == '%esp'): + # Rearrange base and index if it will permit an inline form + base, index = index, base + if base == index: + scale = 1 + base = '$0' + if base != dest and base != '%esp': + # Calculate result directly in dest register + 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) + # 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 +85,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()