[pypy-svn] r35251 - pypy/dist/pypy/jit/codegen/llvm
ericvrp at codespeak.net
ericvrp at codespeak.net
Mon Dec 4 12:48:42 CET 2006
Author: ericvrp
Date: Mon Dec 4 12:48:41 2006
New Revision: 35251
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
Log:
More code taken from jit/codegen/i386
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Mon Dec 4 12:48:41 2006
@@ -1,8 +1,250 @@
+from pypy.rlib.objectmodel import specialize
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
+
+class Var(GenVar):
+
+ def __init__(self):
+ pass
+
+ #repr?
+
+
+class IntConst(GenConst):
+
+ def __init__(self, value):
+ self.value = value
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ if isinstance(T, lltype.Ptr):
+ return lltype.cast_int_to_ptr(T, self.value)
+ elif T is llmemory.Address:
+ return llmemory.cast_int_to_adr(self.value)
+ else:
+ return lltype.cast_primitive(T, self.value)
+
+ #repr?
+
+
+class AddrConst(GenConst):
+
+ def __init__(self, addr):
+ self.addr = addr
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ if T is llmemory.Address:
+ return self.addr
+ elif isinstance(T, lltype.Ptr):
+ return llmemory.cast_adr_to_ptr(self.addr, T)
+ elif T is lltype.Signed:
+ return llmemory.cast_adr_to_int(self.addr)
+ else:
+ assert 0, "XXX not implemented"
+
+ #repr?
+
+
+class Label(GenLabel):
+
+ def __init__(self, startaddr, arg_positions, stackdepth):
+ self.startaddr = startaddr
+ self.arg_positions = arg_positions
+ self.stackdepth = stackdepth
+
+
+class FlexSwitch(CodeGenSwitch):
+
+ #<comment>
+
+ def __init__(self, rgenop):
+ self.rgenop = rgenop
+ self.default_case_addr = 0
+
+ def initialize(self, builder, gv_exitswitch):
+ mc = builder.mc
+ mc.MOV(eax, gv_exitswitch.operand(builder))
+ self.saved_state = builder._save_state()
+ self._reserve(mc)
+
+ 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 = InMemoryCodeBuilder(start, end)
+ fullmc.JMP(rel32(self.nextfreepos))
+ fullmc.done()
+
+ def add_case(self, gv_case):
+ rgenop = self.rgenop
+ targetbuilder = Builder._new_from_state(rgenop, self.saved_state)
+ target_addr = targetbuilder.mc.tell()
+ try:
+ self._add_case(gv_case, target_addr)
+ except CodeBlockOverflow:
+ self._reserve_more()
+ self._add_case(gv_case, target_addr)
+ return targetbuilder
+
+ def _add_case(self, gv_case, target_addr):
+ start = self.nextfreepos
+ end = self.endfreepos
+ mc = InMemoryCodeBuilder(start, end)
+ mc.CMP(eax, gv_case.operand(None))
+ mc.JE(rel32(target_addr))
+ pos = mc.tell()
+ if self.default_case_addr:
+ mc.JMP(rel32(self.default_case_addr))
+ else:
+ illegal_start = mc.tell()
+ mc.JMP(rel32(0))
+ ud2_addr = mc.tell()
+ mc.UD2()
+ illegal_mc = InMemoryCodeBuilder(illegal_start, end)
+ illegal_mc.JMP(rel32(ud2_addr))
+ mc.done()
+ self.nextfreepos = pos
+
+ def add_default(self):
+ rgenop = self.rgenop
+ targetbuilder = Builder._new_from_state(rgenop, self.saved_state)
+ self.default_case_addr = targetbuilder.mc.tell()
+ start = self.nextfreepos
+ end = self.endfreepos
+ mc = InMemoryCodeBuilder(start, end)
+ mc.JMP(rel32(self.default_case_addr))
+ mc.done()
+ return targetbuilder
+
+ #</comment>
+
+
+class Builder(GenBuilder):
+
+ def __init__(self, rgenop):
+ self.rgenop = rgenop
+
+ # ----------------------------------------------------------------
+ # The public Builder interface
+
+ def end(self):
+ pass
+
+ @specialize.arg(1)
+ def genop1(self, opname, gv_arg):
+ genmethod = getattr(self, 'op_' + opname)
+ return genmethod(gv_arg)
+
+ @specialize.arg(1)
+ def genop2(self, opname, gv_arg1, gv_arg2):
+ genmethod = getattr(self, 'op_' + opname)
+ return genmethod(gv_arg1, gv_arg2)
+
+
+
class RLLVMGenOp(AbstractRGenOp):
- pass
+
+ def __init__(self):
+ #self.mcs = [] # machine code blocks where no-one is currently writing
+ #self.keepalive_gc_refs = []
+ pass
+
+ # ----------------------------------------------------------------
+ # the public RGenOp interface
+
+ def openbuilder(self):
+ return Builder(self)
+
+ def newgraph(self, sigtoken, name):
+ numargs = sigtoken # for now
+ builder = self.openbuilder()
+ entrypoint = builder.asm.mc.tell()
+ inputargs_gv = builder._write_prologue(sigtoken)
+ return builder, IntConst(entrypoint), inputargs_gv
+
+ @specialize.genconst(1)
+ def genconst(self, llvalue): #i386 version (ppc version is slightly different)
+ T = lltype.typeOf(llvalue)
+ if T is llmemory.Address:
+ return AddrConst(llvalue)
+ elif isinstance(T, lltype.Primitive):
+ return IntConst(lltype.cast_primitive(lltype.Signed, llvalue))
+ elif isinstance(T, lltype.Ptr):
+ lladdr = llmemory.cast_ptr_to_adr(llvalue)
+ if T.TO._gckind == 'gc':
+ self.keepalive_gc_refs.append(lltype.cast_opaque_ptr(llmemory.GCREF, llvalue))
+ return AddrConst(lladdr)
+ else:
+ assert 0, "XXX not implemented"
+
+ # attached later constPrebuiltGlobal = global_rgenop.genconst
+
+ @staticmethod
+ @specialize.memo()
+ def fieldToken(T, name):
+ return llmemory.offsetof(T, name)
+
+ @staticmethod
+ @specialize.memo()
+ def allocToken(T):
+ return llmemory.sizeof(T)
+
+ @staticmethod
+ @specialize.memo()
+ def varsizeAllocToken(T):
+ if isinstance(T, lltype.Array):
+ return RI386GenOp.arrayToken(T)
+ else:
+ # var-sized structs
+ arrayfield = T._arrayfld
+ ARRAYFIELD = getattr(T, arrayfield)
+ arraytoken = RI386GenOp.arrayToken(ARRAYFIELD)
+ length_offset, items_offset, item_size = arraytoken
+ arrayfield_offset = llmemory.offsetof(T, arrayfield)
+ return (arrayfield_offset+length_offset,
+ arrayfield_offset+items_offset,
+ item_size)
+
+ @staticmethod
+ @specialize.memo()
+ def arrayToken(A):
+ return (llmemory.ArrayLengthOffset(A),
+ llmemory.ArrayItemsOffset(A),
+ llmemory.ItemOffset(A.OF))
+
+ @staticmethod
+ @specialize.memo()
+ def kindToken(T):
+ return None # for now
+
+ @staticmethod
+ @specialize.memo()
+ def sigToken(FUNCTYPE):
+ return len(FUNCTYPE.ARGS) # for now
+
+ @staticmethod
+ def erasedType(T):
+ if T is llmemory.Address:
+ return llmemory.Address
+ if isinstance(T, lltype.Primitive):
+ return lltype.Signed
+ elif isinstance(T, lltype.Ptr):
+ return llmemory.GCREF
+ else:
+ assert 0, "XXX not implemented"
+
global_rgenop = RLLVMGenOp()
-#XXX RLLVMGenOp.constPrebuiltGlobal = global_rgenop.genconst
+RLLVMGenOp.constPrebuiltGlobal = global_rgenop.genconst
More information about the pypy-svn
mailing list