[pypy-svn] r34443 - pypy/dist/pypy/jit/codegen/ppc
mwh at codespeak.net
mwh at codespeak.net
Thu Nov 9 21:40:09 CET 2006
Author: mwh
Date: Thu Nov 9 21:40:06 2006
New Revision: 34443
Modified:
pypy/dist/pypy/jit/codegen/ppc/codebuf.py
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
first implementation of flexswitch for ppc.
i made some very silly mistakes doing this :-)
Modified: pypy/dist/pypy/jit/codegen/ppc/codebuf.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/codebuf.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/codebuf.py Thu Nov 9 21:40:06 2006
@@ -49,12 +49,10 @@
class MachineCodeBlock:
- def __init__(self, map_size):
- assert map_size % 4 == 0
- res = alloc(map_size)
- self._data = cast(res, POINTER(c_int * (map_size / 4)))
- self._size = map_size/4
- self._pos = 0
+ def __init__(self, _data, _size, _pos):
+ self._data = _data
+ self._size = _size
+ self._pos = _pos
def write(self, data):
p = self._pos
@@ -63,9 +61,30 @@
self._data.contents[p] = data
self._pos = p + 1
+ def getpos(self):
+ return self._pos
+
+ def setpos(self, _pos):
+ self._pos = _pos
+
def tell(self):
baseaddr = cast(self._data, c_void_p).value
return baseaddr + self._pos * 4
+ def reserve(self, _size):
+ r = MachineCodeBlock(self._data, self._pos + _size, self._pos)
+ for i in range(_size):
+ self.write(0)
+ return r
+
+class OwningMachineCodeBlock(MachineCodeBlock):
def __del__(self):
free(cast(self._data, PTR), self._size * 4)
+
+def new_block(size_in_bytes):
+ assert size_in_bytes % 4 == 0
+ res = alloc(size_in_bytes)
+ return OwningMachineCodeBlock(
+ cast(res, POINTER(c_int * (size_in_bytes / 4))),
+ size_in_bytes/4,
+ 0)
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Thu Nov 9 21:40:06 2006
@@ -297,3 +297,18 @@
def emit(self, asm):
if self.reg.number != 3:
asm.mr(r3, self.reg.number)
+
+class FakeUse(Insn):
+ """ A fake use of a var to get it into a register. And reserving
+ a condition register field."""
+ def __init__(self, rvar, var):
+ Insn.__init__(self)
+ self.var = var
+ self.reg_args = [self.var]
+ self.reg_arg_regclasses = [GP_REGISTER]
+ self.result = rvar
+ self.result_regclass = CR_FIELD
+ def allocate(self, allocator):
+ pass
+ def emit(self, asm):
+ pass
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Thu Nov 9 21:40:06 2006
@@ -260,7 +260,17 @@
self.asm.bctr()
self._close()
-## def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch):
+ # make sure the exitswitch ends the block in a register:
+ crresult = Var()
+ self.insns.append(insn.FakeUse(crresult, gv_exitswitch))
+ allocator = self.allocate_and_emit()
+ switch_mc = self.asm.mc.reserve(7 * 5 + 4)
+ self._close()
+ return FlexSwitch(self.rgenop, switch_mc,
+ allocator.loc_of(gv_exitswitch),
+ allocator.loc_of(crresult),
+ allocator.var2loc)
# ----------------------------------------------------------------
# ppc-specific interface:
@@ -551,45 +561,68 @@
if self.mcs:
return self.mcs.pop()
else:
- return codebuf.MachineCodeBlock(65536) # XXX supposed infinite for now
+ return codebuf.new_block(65536) # XXX supposed infinite for now
def close_mc(self, mc):
+## from pypy.translator.asm.ppcgen.asmfunc import get_ppcgen
+## print '!!!!', cast(mc._data, c_void_p).value
+## print '!!!!', mc._data.contents[0]
+## get_ppcgen().flush2(cast(mc._data, c_void_p).value,
+## mc._size*4)
self.mcs.append(mc)
def openbuilder(self):
return Builder(self, self.open_mc())
-## class FlexSwitch(CodeGenSwitch):
+# a switch can take 7 instructions:
-## def __init__(self, rgenop):
-## self.rgenop = rgenop
-## self.default_case_addr = 0
-
-## def initialize(self, builder, gv_exitswitch):
-## self.switch_reg = gv_exitswitch.load(builder)
-## self.saved_state = builder._save_state()
-## self._reserve(mc)
-
-## def _reserve(self, mc):
-## RESERVED = 11 # enough for 5 cases and a default
-## pos = mc.tell()
-## for i in range(RESERVED):
-## mc.write(0)
-## self.nextfreepos = pos
-## self.endfreepos = pos + RESERVED * 4
+# load_word rSCRATCH, gv_case.value (really two instructions)
+# cmpw crf, rSWITCH, rSCRATCH
+# load_word rSCRATCH, targetaddr (again two instructions)
+# mtctr rSCRATCH
+# beqctr crf
+
+# yay RISC :/
+
+class FlexSwitch(CodeGenSwitch):
+
+ def __init__(self, rgenop, mc, switch_reg, crf, var2loc):
+ self.rgenop = rgenop
+ self.crf = crf
+ self.switch_reg = switch_reg
+ self.var2loc = var2loc
+ self.asm = RPPCAssembler()
+ self.asm.mc = mc
+ self.default_target_addr = 0
## def _reserve_more(self):
## XXX
-## start = self.nextfreepos
-## end = self.endfreepos
-## newmc = self.rgenop.open_mc()
-## self._reserve(newmc)
-## self.rgenop.close_mc(newmc)
-## fullmc = InMemoryCodeBuilder(start, end)
-## a = RPPCAssembler()
-## a.mc = newmc
-## fullmc.ba(rel32(self.nextfreepos))
-## fullmc.done()
-## def add_case(self, gv_case):
-## def add_default(self):
+ def add_case(self, gv_case):
+ targetbuilder = self.rgenop.openbuilder()
+ targetbuilder.make_fresh_from_jump(self.var2loc)
+ target_addr = targetbuilder.asm.mc.tell()
+ asm = self.asm
+ assert isinstance(gv_case, IntConst)
+ asm.load_word(rSCRATCH, gv_case.value)
+ asm.cmpw(self.crf.number, rSCRATCH, self.switch_reg.number)
+ asm.load_word(rSCRATCH, target_addr)
+ asm.mtctr(rSCRATCH)
+ asm.bcctr(12, self.crf.number*4 + 2)
+ if self.default_target_addr:
+ self._write_default()
+ return targetbuilder
+
+ def add_default(self):
+ targetbuilder = self.rgenop.openbuilder()
+ targetbuilder.make_fresh_from_jump(self.var2loc)
+ self.default_target_addr = targetbuilder.asm.mc.tell()
+ self._write_default()
+ return targetbuilder
+
+ def _write_default(self):
+ pos = self.asm.mc.getpos()
+ self.asm.load_word(rSCRATCH, self.default_target_addr)
+ self.asm.mtctr(rSCRATCH)
+ self.asm.bctr()
+ self.asm.mc.setpos(pos)
More information about the Pypy-commit
mailing list