[SeaBIOS] [PATCHv2 3/3] vgabios: Optimize leal instruction fixup

Kevin O'Connor kevin at koconnor.net
Fri Apr 10 18:19:48 CEST 2015


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 at 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()
-- 
1.9.3




More information about the SeaBIOS mailing list