[pypy-svn] r36688 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
arigo at codespeak.net
arigo at codespeak.net
Sat Jan 13 19:00:58 CET 2007
Author: arigo
Date: Sat Jan 13 19:00:55 2007
New Revision: 36688
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Flexswitches. More small fixes.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 19:00:55 2007
@@ -6,6 +6,7 @@
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.jit.codegen.i386.ri386 import *
from pypy.jit.codegen.i386.ri386setup import Conditions
+from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow
from pypy.jit.codegen.i386 import conftest
@@ -399,6 +400,69 @@
# ____________________________________________________________
+class FlexSwitch(CodeGenSwitch):
+ REG = eax
+
+ def __init__(self, rgenop, inputargs_gv, inputoperands):
+ self.rgenop = rgenop
+ self.inputargs_gv = inputargs_gv
+ self.inputoperands = inputoperands
+ self.defaultcaseaddr = 0
+
+ def initialize(self, mc):
+ self._reserve(mc)
+ default_builder = Builder(self.rgenop, self.inputargs_gv,
+ self.inputoperands)
+ default_builder.set_coming_from(mc)
+ default_builder.update_defaultcaseaddr_of = self
+ default_builder.start_writing()
+ return default_builder
+
+ def _reserve(self, mc):
+ RESERVED = 11*4+5 # XXX quite a lot for now :-/
+ pos = mc.tell()
+ mc.UD2()
+ mc.write('\x00' * (RESERVED-1))
+ self.nextfreepos = pos
+ self.endfreepos = pos + RESERVED
+
+ def _reserve_more(self):
+ start = self.nextfreepos
+ end = self.endfreepos
+ newmc = self.rgenop.open_mc()
+ self._reserve(newmc)
+ self.rgenop.close_mc(newmc)
+ fullmc = self.rgenop.InMemoryCodeBuilder(start, end)
+ fullmc.JMP(rel32(self.nextfreepos))
+ fullmc.done()
+
+ def add_case(self, gv_case):
+ rgenop = self.rgenop
+ targetbuilder = Builder(self.rgenop, self.inputargs_gv,
+ self.inputoperands)
+ try:
+ self._add_case(gv_case, targetbuilder)
+ except CodeBlockOverflow:
+ self._reserve_more()
+ self._add_case(gv_case, targetbuilder)
+ targetbuilder.start_writing()
+ return targetbuilder
+
+ def _add_case(self, gv_case, targetbuilder):
+ start = self.nextfreepos
+ end = self.endfreepos
+ mc = self.rgenop.InMemoryCodeBuilder(start, end)
+ value = gv_case.revealconst(lltype.Signed)
+ mc.CMP(FlexSwitch.REG, imm(value))
+ targetbuilder.set_coming_from(mc, Conditions['E'])
+ pos = mc.tell()
+ assert self.defaultcaseaddr != 0
+ mc.JMP(rel32(self.defaultcaseaddr))
+ mc.done()
+ self.nextfreepos = pos
+
+# ____________________________________________________________
+
def setup_opclasses(base):
d = {}
for name, value in globals().items():
@@ -544,23 +608,24 @@
if at_start:
pass # input variable not used anyway
else:
- self.add_final_move(v, operand)
+ self.add_final_move(v, operand, make_copy=v.is_const)
else:
if loc in force_loc2operand or operand in force_operand2loc:
if at_start:
self.initial_moves.append((loc, operand))
else:
- self.add_final_move(v, operand)
+ self.add_final_move(v, operand, make_copy=True)
else:
force_loc2operand[loc] = operand
force_operand2loc[operand] = loc
- def add_final_move(self, v, targetoperand):
- v2 = OpSameAs(v)
- self.operations.append(v2)
+ def add_final_move(self, v, targetoperand, make_copy):
+ if make_copy:
+ v = OpSameAs(v)
+ self.operations.append(v)
loc = self.nextloc
self.nextloc += 1
- self.var2loc[v2] = loc
+ self.var2loc[v] = loc
self.force_loc2operand[loc] = targetoperand
def allocate_registers(self):
@@ -653,6 +718,7 @@
class Builder(GenBuilder):
coming_from = 0
operations = None
+ update_defaultcaseaddr_of = None
def __init__(self, rgenop, inputargs_gv, inputoperands):
self.rgenop = rgenop
@@ -717,6 +783,8 @@
start = self.coming_from
if start:
targetaddr = mc.tell()
+ if self.update_defaultcaseaddr_of: # hack for FlexSwitch
+ self.update_defaultcaseaddr_of.defaultcaseaddr = targetaddr
end = start + 6 # XXX hard-coded, enough for JMP and Jcond
oldmc = self.rgenop.InMemoryCodeBuilder(start, end)
insn = EMIT_JCOND[self.coming_from_cond]
@@ -797,6 +865,21 @@
self.operations.append(op)
return op
+ def flexswitch(self, gv_exitswitch, args_gv):
+ reg = FlexSwitch.REG
+ mc = self.generate_block_code(args_gv, [gv_exitswitch], [reg],
+ renaming=False)
+ result = FlexSwitch(self.rgenop, self.inputargs_gv, self.inputoperands)
+ default_builder = result.initialize(mc)
+ self.rgenop.close_mc(mc)
+ return result, default_builder
+
+ def show_incremental_progress(self):
+ pass
+
+ def log(self, msg):
+ self.mc.log(msg)
+
class RI386GenOp(AbstractRGenOp):
from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
More information about the Pypy-commit
mailing list