[pypy-svn] r18348 - in pypy/dist/pypy/translator: . asm asm/ppcgen asm/ppcgen/test asm/test tool/pygame
mwh at codespeak.net
mwh at codespeak.net
Mon Oct 10 19:49:36 CEST 2005
Author: mwh
Date: Mon Oct 10 19:49:28 2005
New Revision: 18348
Added:
pypy/dist/pypy/translator/asm/
pypy/dist/pypy/translator/asm/__init__.py
pypy/dist/pypy/translator/asm/autopath.py
pypy/dist/pypy/translator/asm/genasm.py
pypy/dist/pypy/translator/asm/ppcgen/
pypy/dist/pypy/translator/asm/ppcgen/__init__.py
pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c
pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py
pypy/dist/pypy/translator/asm/ppcgen/assembler.py
pypy/dist/pypy/translator/asm/ppcgen/autopath.py
pypy/dist/pypy/translator/asm/ppcgen/field.py
pypy/dist/pypy/translator/asm/ppcgen/form.py
pypy/dist/pypy/translator/asm/ppcgen/func_builder.py
pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py
pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py
pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py
pypy/dist/pypy/translator/asm/ppcgen/pystructs.py
pypy/dist/pypy/translator/asm/ppcgen/regname.py
pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py
pypy/dist/pypy/translator/asm/ppcgen/test/
pypy/dist/pypy/translator/asm/ppcgen/test/__init__.py
pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py
pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py
pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py
pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py
pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py
pypy/dist/pypy/translator/asm/ppcgen/util.py
pypy/dist/pypy/translator/asm/test/
pypy/dist/pypy/translator/asm/test/__init__.py
pypy/dist/pypy/translator/asm/test/autopath.py
pypy/dist/pypy/translator/asm/test/test_asm.py
Modified:
pypy/dist/pypy/translator/tool/pygame/graphdisplay.py
pypy/dist/pypy/translator/translator.py
Log:
(andrewt, mwh)
very first cut of the ppc32 backend. works for a couple of toy
integer using examples. hope i've disabled all the relavent tests
for non-PPC :)
includes an adapted version of my (mwh's) ppy package.
Added: pypy/dist/pypy/translator/asm/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/__init__.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1 @@
+# ppc only for now!!
Added: pypy/dist/pypy/translator/asm/autopath.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/autopath.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,120 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories don't have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.realpath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ break
+ else:
+ raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+
+ checkpaths = sys.path[:]
+ pypy_root = os.path.join(head, '')
+
+ while checkpaths:
+ orig = checkpaths.pop()
+ fullorig = os.path.join(os.path.realpath(orig), '')
+ if fullorig.startswith(pypy_root):
+ if os.path.exists(os.path.join(fullorig, '__init__.py')):
+ sys.path.remove(orig)
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+
+ munged = {}
+ for name, mod in sys.modules.items():
+ fn = getattr(mod, '__file__', None)
+ if '.' in name or not isinstance(fn, str):
+ continue
+ newname = os.path.splitext(os.path.basename(fn))[0]
+ if not newname.startswith(part + '.'):
+ continue
+ path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+ if path.startswith(pypy_root) and newname != part:
+ modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+ if newname != '__init__':
+ modpaths.append(newname)
+ modpath = '.'.join(modpaths)
+ if modpath not in sys.modules:
+ munged[modpath] = mod
+
+ for name, mod in munged.iteritems():
+ if name not in sys.modules:
+ sys.modules[name] = mod
+ if '.' in name:
+ prename = name[:name.rfind('.')]
+ postname = name[len(prename)+1:]
+ if prename not in sys.modules:
+ __import__(prename)
+ if not hasattr(sys.modules[prename], postname):
+ setattr(sys.modules[prename], postname, mod)
+
+ return partdir, this_dir
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/dist/pypy/translator/asm/genasm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/genasm.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,119 @@
+from pypy.objspace.flow.model import traverse, Block, Variable, Constant
+from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler
+from pypy.translator.asm.ppcgen.func_builder import make_func
+
+def genlinkcode(link):
+ for s, t in zip(link.args, link.target.inputargs):
+ print ' ', 'mr', t, s
+
+
+def genasm(translator):
+
+ f = translator.entrypoint
+
+ graph = translator.getflowgraph(f)
+
+ g = FuncGenerator(graph)
+ g.gencode()
+ return make_func(g.assembler, 'i', 'ii')
+
+
+class FuncGenerator(object):
+
+ def __init__(self, graph):
+ self.graph = graph
+ self.allblocks = []
+ self.blocknum = {}
+ def visit(block):
+ if isinstance(block, Block):
+ self.allblocks.append(block)
+ self.blocknum[block] = len(self.blocknum)
+ traverse(visit, graph)
+ self._var2reg = {}
+ self.next_register = 3
+ for var in graph.startblock.inputargs:
+ self.assign_register(var)
+ self._block_counter = 0
+ self.assembler = PPCAssembler()
+
+ def assign_register(self, var):
+ assert var not in self._var2reg
+ self._var2reg[var] = self.next_register
+ self.next_register += 1
+
+ def reg(self, var):
+ assert isinstance(var, Variable)
+ if var not in self._var2reg:
+ self.assign_register(var)
+ return self._var2reg[var]
+
+ def blockname(self):
+ self._block_counter += 1
+ return 'anonblock' + str(self._block_counter)
+
+ def genlinkcode(self, link):
+ for s, t in zip(link.args, link.target.inputargs):
+ self.assembler.mr(self.reg(t), self.reg(s))
+ self.assembler.b('block' + str(self.blocknum[link.target]))
+
+ def genblockcode(self, block):
+ self.assembler.label('block'+str(self.blocknum[block]))
+ for op in block.operations:
+ print self.reg(op.result), op, op.args
+ getattr(self, op.opname)(op.result, *op.args)
+ assert len(block.exits) in [0, 1, 2]
+ if len(block.exits) == 2:
+ assert block.exitswitch is not None
+ truelink, falselink = block.exits
+ b = self.blockname()
+ self.assembler.cmpwi(0, self.reg(block.exitswitch), 1)
+ self.assembler.bne(b)
+ self.genlinkcode(truelink)
+ self.assembler.label(b)
+ self.genlinkcode(falselink)
+ elif len(block.exits) == 1:
+ self.genlinkcode(block.exits[0])
+ else:
+ self.assembler.mr(3, self.reg(block.inputargs[0]))
+ self.assembler.blr()
+
+ def gencode(self):
+ #print map(self.reg, self.graph.startblock.inputargs)
+ for block in self.allblocks:
+ self.genblockcode(block)
+
+ def int_add(self, dest, v1, v2):
+ if isinstance(v1, Constant):
+ self.assembler.addi(self.reg(dest), self.reg(v2), v1.value)
+ elif isinstance(v2, Constant):
+ self.assembler.addi(self.reg(dest), self.reg(v1), v2.value)
+ else:
+ self.assembler.add(self.reg(dest), self.reg(v1), self.reg(v2))
+
+ def int_sub(self, dest, v1, v2):
+ if isinstance(v1, Constant):
+ self.assembler.subfi(self.reg(dest), self.reg(v2), v1.value)
+ elif isinstance(v2, Constant):
+ self.assembler.addi(self.reg(dest), self.reg(v1), -v2.value)
+ else:
+ self.assembler.sub(self.reg(dest), self.reg(v1), self.reg(v2))
+
+ def int_gt(self, dest, v1, v2):
+ conditional = 'bgt'
+ if isinstance(v1, Constant):
+ conditional = 'ble'
+ self.assembler.cmpwi(0, self.reg(v2), v1.value)
+ elif isinstance(v2, Constant):
+ self.assembler.cmpwi(0, self.reg(v1), v2.value)
+ else:
+ self.assembler.cmpw(0, self.reg(v2), self.reg(v1))
+ b = self.blockname()
+ self.assembler.xor(self.reg(dest), self.reg(dest), self.reg(dest))
+ getattr(self.assembler, conditional)(b)
+ self.assembler.addi(self.reg(dest), self.reg(dest), 1)
+ self.assembler.label(b)
+
+ def same_as(self, dest, v1):
+ self.assembler.mr(self.reg(dest), self.reg(v1))
+
+
Added: pypy/dist/pypy/translator/asm/ppcgen/__init__.py
==============================================================================
Added: pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c Mon Oct 10 19:49:28 2005
@@ -0,0 +1,150 @@
+#include <Python.h>
+#include <sys/mman.h>
+
+#define __dcbf(base, index) \
+ __asm__ ("dcbf %0, %1" : /*no result*/ : "b%" (index), "r" (base) : "memory")
+
+
+static PyTypeObject* mmap_type;
+
+#if defined(__APPLE__)
+
+#include <mach-o/dyld.h>
+
+static PyObject*
+_ppy_NSLookupAndBindSymbol(PyObject* self, PyObject* args)
+{
+ char *s;
+ NSSymbol sym;
+
+ if (!PyArg_ParseTuple(args, "s", &s))
+ return NULL;
+
+ if (!NSIsSymbolNameDefined(s)) {
+ return PyErr_Format(PyExc_ValueError,
+ "symbol '%s' not found", s);
+ }
+
+ sym = NSLookupAndBindSymbol(s);
+
+ return PyInt_FromLong((long)NSAddressOfSymbol(sym));
+}
+
+
+#elif defined(linux)
+
+#include <dlfcn.h>
+
+static PyObject*
+_ppy_dlsym(PyObject* self, PyObject* args)
+{
+ char *s;
+ void *handle;
+ void *sym;
+
+ if (!PyArg_ParseTuple(args, "s", &s))
+ return NULL;
+
+ handle = dlopen(RTLD_DEFAULT, RTLD_LAZY);
+ sym = dlsym(handle, s);
+ if (sym == NULL) {
+ return PyErr_Format(PyExc_ValueError,
+ "symbol '%s' not found", s);
+ }
+ return PyInt_FromLong((long)sym);
+}
+
+#else
+
+#error "OS not supported"
+
+#endif
+
+
+static PyObject*
+_ppy_mmap_exec(PyObject* self, PyObject* args)
+{
+ PyObject* code_args;
+ PyObject* r;
+ PyObject* mmap_obj;
+ char* code;
+ size_t size;
+
+ if (!PyArg_ParseTuple(args, "O!O!:mmap_exec",
+ mmap_type, &mmap_obj,
+ &PyTuple_Type, &code_args))
+ return NULL;
+
+ code = *((char**)mmap_obj + 2);
+ size = *((size_t*)mmap_obj + 3);
+
+ r = ((PyCFunction)code)(NULL, code_args);
+
+ Py_DECREF(args);
+
+ return r;
+}
+
+static PyObject*
+_ppy_mmap_flush(PyObject* self, PyObject* arg)
+{
+ char* code;
+ size_t size;
+ int i = 0;
+
+ if (!PyObject_TypeCheck(arg, mmap_type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "mmap_flush: single argument must be mmap object");
+ }
+
+ code = *((char**)arg + 2);
+ size = *((size_t*)arg + 3);
+
+ for (; i < size; i += 32){
+ __dcbf(code, i);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyMethodDef _ppy_methods[] = {
+#if defined(__APPLE__)
+ {"NSLookupAndBindSymbol", _ppy_NSLookupAndBindSymbol,
+ METH_VARARGS, ""},
+#elif defined(linux)
+ {"dlsym", _ppy_dlsym, METH_VARARGS, ""},
+#endif
+ {"mmap_exec", _ppy_mmap_exec, METH_VARARGS, ""},
+ {"mmap_flush", _ppy_mmap_flush, METH_O, ""},
+ {0, 0}
+};
+
+PyMODINIT_FUNC
+init_ppcgen(void)
+{
+ PyObject* m;
+ PyObject* mmap_module;
+ PyObject* mmap_func;
+ PyObject* mmap_obj;
+
+ m = Py_InitModule("_ppcgen", _ppy_methods);
+
+ /* argh */
+ /* time to campaign for a C API for the mmap module! */
+ mmap_module = PyImport_ImportModule("mmap");
+ if (!mmap_module)
+ return;
+ mmap_func = PyObject_GetAttrString(mmap_module, "mmap");
+ if (!mmap_func)
+ return;
+ mmap_obj = PyEval_CallFunction(mmap_func, "iii", -1, 0, MAP_ANON);
+ if (!mmap_obj)
+ return;
+ mmap_type = mmap_obj->ob_type;
+ Py_INCREF(mmap_type);
+ Py_DECREF(mmap_obj);
+ Py_DECREF(mmap_func);
+ Py_DECREF(mmap_module);
+}
Added: pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,16 @@
+import py
+_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule()
+import mmap, struct
+
+class AsmCode(object):
+ def __init__(self, size):
+ self.code = mmap.mmap(-1, size,
+ mmap.MAP_ANON|mmap.MAP_PRIVATE,
+ mmap.PROT_WRITE|mmap.PROT_READ|mmap.PROT_EXEC)
+ def emit(self, insn):
+ self.code.write(struct.pack('i', insn))
+ def __call__(self, *args):
+ return _ppcgen.mmap_exec(self.code, args)
+ def flush_cache(self):
+ _ppcgen.mmap_flush(self.code)
+
Added: pypy/dist/pypy/translator/asm/ppcgen/assembler.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/assembler.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,77 @@
+import array
+import os
+from pypy.translator.asm.ppcgen import form
+
+# don't be fooled by the fact that there's some separation between a
+# generic assembler class and a PPC assembler class... there's
+# certainly a RISC dependency in here, and quite possibly a PPC
+# dependency or two too. I personally don't care :)
+
+class AssemblerException(Exception):
+ pass
+
+class Assembler(object):
+ def __init__(self):
+ self.insts = []
+ self.labels = {}
+ self.rlabels = {}
+
+ def label(self, name):
+ if name in self.labels:
+ raise AssemblerException, "duplicate label '%s'"%(name,)
+ self.labels[name] = len(self.insts)*4
+ self.rlabels.setdefault(len(self.insts)*4, []).append(name)
+
+ def labelname(self, base="L"):
+ i = 0
+ while 1:
+ ln = base + str(i)
+ if ln not in self.labels:
+ return ln
+ i += 1
+
+ def assemble0(self, dump=os.environ.has_key('PPY_DEBUG')):
+ for i, inst in enumerate(self.insts):
+ for f in inst.lfields:
+ l = self.labels[inst.fields[f]] - 4*i
+ inst.fields[f] = l
+ buf = []
+ for inst in self.insts:
+ buf.append(inst.assemble())
+ if dump:
+ for i in range(len(buf)):
+ inst = self.disassemble(buf[i], self.rlabels, i*4)
+ for lab in self.rlabels.get(4*i, []):
+ print "%s:"%(lab,)
+ print "\t%4d %s"%(4*i, inst)
+ return buf
+
+ def assemble(self, dump=os.environ.has_key('PPY_DEBUG')):
+ insns = self.assemble0(dump)
+ from pypy.translator.asm.ppcgen import asmfunc
+ c = asmfunc.AsmCode(len(insns)*4)
+ for i in insns:
+ c.emit(i)
+ c.flush_cache()
+ return c
+
+ def get_idescs(cls):
+ r = []
+ for name in dir(cls):
+ a = getattr(cls, name)
+ if isinstance(a, form.IDesc):
+ r.append((name, a))
+ return r
+ get_idescs = classmethod(get_idescs)
+
+ def disassemble(cls, inst, labels={}, pc=0):
+ matches = []
+ idescs = cls.get_idescs()
+ for name, idesc in idescs:
+ m = idesc.match(inst)
+ if m > 0:
+ matches.append((m, idesc, name))
+ if matches:
+ score, idesc, name = max(matches)
+ return idesc.disassemble(name, inst, labels, pc)
+ disassemble = classmethod(disassemble)
Added: pypy/dist/pypy/translator/asm/ppcgen/autopath.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/autopath.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,120 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories don't have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.realpath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ break
+ else:
+ raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+
+ checkpaths = sys.path[:]
+ pypy_root = os.path.join(head, '')
+
+ while checkpaths:
+ orig = checkpaths.pop()
+ fullorig = os.path.join(os.path.realpath(orig), '')
+ if fullorig.startswith(pypy_root):
+ if os.path.exists(os.path.join(fullorig, '__init__.py')):
+ sys.path.remove(orig)
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+
+ munged = {}
+ for name, mod in sys.modules.items():
+ fn = getattr(mod, '__file__', None)
+ if '.' in name or not isinstance(fn, str):
+ continue
+ newname = os.path.splitext(os.path.basename(fn))[0]
+ if not newname.startswith(part + '.'):
+ continue
+ path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+ if path.startswith(pypy_root) and newname != part:
+ modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+ if newname != '__init__':
+ modpaths.append(newname)
+ modpath = '.'.join(modpaths)
+ if modpath not in sys.modules:
+ munged[modpath] = mod
+
+ for name, mod in munged.iteritems():
+ if name not in sys.modules:
+ sys.modules[name] = mod
+ if '.' in name:
+ prename = name[:name.rfind('.')]
+ postname = name[len(prename)+1:]
+ if prename not in sys.modules:
+ __import__(prename)
+ if not hasattr(sys.modules[prename], postname):
+ setattr(sys.modules[prename], postname, mod)
+
+ return partdir, this_dir
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/dist/pypy/translator/asm/ppcgen/field.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/field.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,61 @@
+# only a small file, but there's some hairy stuff in here!
+"""
+>>> f = Field('test', 16, 31)
+>>> f
+<Field 'test'>
+>>> f.encode(65535)
+65535
+>>> f.encode(65536)
+Traceback (most recent call last):
+ File \"<stdin>\", line 1, in ?
+ File \"field.py\", line 25, in encode
+ raise ValueError(\"field '%s' can't accept value %s\"
+ValueError: field 'test' can't accept value 65536
+>>>
+
+"""
+
+
+class Field(object):
+ def __init__(self, name, left, right, signedness=False, valclass=int):
+ self.name = name
+ self.left = left
+ self.right = right
+ width = self.right - self.left + 1
+ # mask applies before shift!
+ self.mask = 2**width - 1
+ self.signed = signedness == 'signed'
+ self.valclass = valclass
+ def __repr__(self):
+ return '<Field %r>'%(self.name,)
+ def encode(self, value):
+ if not issubclass(self.valclass, type(value)):
+ raise ValueError("field '%s' takes '%s's, not '%s's"
+ %(self.name, self.valclass.__name__, type(value).__name__))
+ if not self.signed and value < 0:
+ raise ValueError("field '%s' is unsigned and can't accept value %d"
+ %(self.name, value))
+ # that this does the right thing is /not/ obvious (but true!)
+ if ((value >> 31) ^ value) & ~(self.mask >> self.signed):
+ raise ValueError("field '%s' can't accept value %s"
+ %(self.name, value))
+ value &= self.mask
+ value = long(value)
+ value <<= (32 - self.right - 1)
+ if value & 0x80000000L:
+ # yuck:
+ return ~int((~value)&0xFFFFFFFFL)
+ else:
+ return int(value)
+ def decode(self, inst):
+ mask = self.mask
+ v = (inst >> 32 - self.right - 1) & mask
+ if self.signed and (~mask >> 1) & mask & v:
+ v = ~(~v&mask)
+ return self.valclass(v)
+ def r(self, v, labels, pc):
+ return self.decode(v)
+
+if __name__=='__main__':
+ import doctest
+ doctest.testmod()
Added: pypy/dist/pypy/translator/asm/ppcgen/form.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/form.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,191 @@
+
+# XXX there is much grot here.
+
+# some of this comes from trying to present a reasonably intuitive and
+# useful interface, which implies a certain amount of DWIMmery.
+# things surely still could be more transparent.
+
+class FormException(Exception):
+ pass
+
+
+class Instruction(object):
+ def __init__(self, fields):
+ self.fields = fields
+ self.lfields = [k for (k,v) in fields.iteritems()
+ if isinstance(v, str)]
+ if not self.lfields:
+ self.assemble() # for error checking only
+ def assemble(self):
+ r = 0
+ for field in self.fields:
+ r |= field.encode(self.fields[field])
+ return r
+
+
+class IBoundDesc(object):
+ def __init__(self, desc, fieldmap, assembler):
+ self.fieldmap = fieldmap
+ self.desc = desc
+ self.assembler = assembler
+ def calc_fields(self, args, kw):
+ fieldsleft = list(self.desc.fields)
+ fieldvalues = {}
+ for fname in kw:
+ kw[fname] = self.fieldmap[fname]
+ for d in (self.desc.specializations, kw):
+ for field in d:
+ fieldsleft.remove(field)
+ fieldvalues[field] = d[field]
+ for i in range(min(len(self.desc.defaults), len(fieldsleft) - len(args))):
+ f, v = self.desc.defaults[i]
+ fieldvalues[f] = v
+ fieldsleft.remove(f)
+ for a in args:
+ field = fieldsleft.pop(0)
+ fieldvalues[field] = a
+ return fieldvalues, fieldsleft
+ def __call__(self, *args, **kw):
+ fieldvalues, sparefields = self.calc_fields(args, kw)
+ if sparefields:
+ raise FormException, 'fields %s left'%sparefields
+ self.assembler.insts.append(Instruction(fieldvalues))
+
+
+class IBoundDupDesc(IBoundDesc):
+ def calc_fields(self, args, kw):
+ s = super(IBoundDupDesc, self)
+ fieldvalues, sparefields = s.calc_fields(args, kw)
+ for k, v in self.desc.dupfields.iteritems():
+ fieldvalues[k] = fieldvalues[v]
+ return fieldvalues, sparefields
+
+
+class IDesc(object):
+ boundtype = IBoundDesc
+ def __init__(self, fieldmap, fields, specializations, boundtype=None):
+ self.fieldmap = fieldmap
+ self.fields = fields
+ self.specializations = specializations
+ self.defaults = ()
+ if boundtype is not None:
+ self.boundtype = boundtype
+ for field in specializations:
+ if field not in fields:
+ raise FormException, field
+
+ def __get__(self, ob, cls=None):
+ if ob is None: return self
+ return self.boundtype(self, self.fieldmap, ob)
+
+ def default(self, **defs):
+ assert len(defs) == 1
+ f, v = defs.items()[0]
+ self.defaults = self.defaults + ((self.fieldmap[f], v),)
+ return self
+
+ def __call__(self, **more_specializatons):
+ s = self.specializations.copy()
+ ms = {}
+ ds = {}
+ for fname, v in more_specializatons.iteritems():
+ field = self.fieldmap[fname]
+ if field not in self.fields:
+ raise FormException, "don't know about '%s' here"%k
+ if isinstance(v, str):
+ ds[field] = self.fieldmap[v]
+ else:
+ ms[field] = v
+ s.update(ms)
+ if len(s) != len(self.specializations) + len(ms):
+ raise FormException, "respecialization not currently allowed"
+ if ds:
+ fields = list(self.fields)
+ for field in ds:
+ fields.remove(field)
+ return IDupDesc(self.fieldmap, tuple(fields), s, ds)
+ else:
+ r = IDesc(self.fieldmap, self.fields, s, self.boundtype)
+ r.defaults = tuple([(f, d) for (f, d) in self.defaults if f not in s])
+ return r
+
+ def match(self, inst):
+ c = 0
+ for field in self.fields:
+ if field in self.specializations:
+ if field.decode(inst) != self.specializations[field]:
+ return 0
+ else:
+ c += 1
+ return c
+
+ def __repr__(self):
+ l = []
+ for field in self.fields:
+ if field in self.specializations:
+ l.append('%s=%r'%(field.name, self.specializations[field]))
+ else:
+ l.append(field.name)
+ r = '%s(%s)'%(self.__class__.__name__, ', '.join(l))
+ if self.boundtype is not self.__class__.boundtype:
+ r += ' => ' + self.boundtype.__name__
+ return r
+
+ def disassemble(self, name, inst, labels, pc):
+ kws = []
+ for field in self.fields:
+ if field not in self.specializations:
+ v = field.decode(inst)
+ for f, d in self.defaults:
+ if f is field:
+ if d == v:
+ break
+ else:
+ kws.append('%s=%s'%(field.name, field.r(inst, labels, pc)))
+ return "%-5s %s"%(name, ', '.join(kws))
+
+
+class IDupDesc(IDesc):
+ boundtype = IBoundDupDesc
+ def __init__(self, fieldmap, fields, specializations, dupfields):
+ super(IDupDesc, self).__init__(fieldmap, fields, specializations)
+ self.dupfields = dupfields
+
+ def match(self, inst):
+ for field in self.dupfields:
+ df = self.dupfields[field]
+ if field.decode(inst) != df.decode(inst):
+ return 0
+ else:
+ return super(IDupDesc, self).match(inst)
+
+
+class Form(object):
+ fieldmap = None
+ def __init__(self, *fnames):
+ self.fields = []
+ bits = {}
+ for fname in fnames:
+ if isinstance(fname, str):
+ field = self.fieldmap[fname]
+ else:
+ field = fname
+ for b in range(field.left, field.right+1):
+ if b in bits:
+ raise FormException, "'%s' and '%s' clash at bit '%s'"%(
+ bits[b], fname, b)
+ else:
+ bits[b] = fname
+ self.fields.append(field)
+
+ def __call__(self, **specializations):
+ s = {}
+ for fname in specializations:
+ field = self.fieldmap[fname]
+ if field not in self.fields:
+ raise FormException, "no nothin bout '%s'"%k
+ s[field] = specializations[fname]
+ return IDesc(self.fieldmap, self.fields, s)
+
+ def __repr__(self):
+ return '%s(%r)'%(self.__class__.__name__, [f.name for f in self.fields])
Added: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,158 @@
+from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler
+from pypy.translator.asm.ppcgen.symbol_lookup import lookup
+from pypy.translator.asm.ppcgen.regname import *
+
+def load_arg(code, argi, typecode):
+ rD = r3+argi
+ code.lwz(rD, r4, 12 + 4*argi)
+ if typecode == 'i':
+ code.load_word(r0, lookup("PyInt_Type"))
+ code.lwz(r15, rD, 4) # XXX ick!
+ code.cmpw(r0, r15)
+ code.bne("argserror")
+ code.lwz(rD, rD, 8)
+ elif typecode == 'f':
+ code.load_word(r0, lookup("PyFloat_Type"))
+ code.lwz(r15, rD, 4)
+ code.cmpw(r0, r15)
+ code.bne("argserror")
+ code.lfd(rD-2, rD, 8)
+ elif typecode != "O":
+ raise Exception, "erk"
+
+FAST_ENTRY_LABEL = "FAST-ENTRY-LABEL"
+
+def make_func(code, retcode, signature):
+ """code shouldn't contain prologue/epilogue (or touch r31)"""
+
+ argcount = len(signature)
+
+ ourcode = MyPPCAssembler()
+ ourcode.mflr(r0)
+ ourcode.stmw(r31, r1, -4)
+ ourcode.stw(r0, r1, 8)
+ ourcode.stwu(r1, r1, -80)
+
+ ourcode.lwz(r3, r4, 8)
+ ourcode.cmpwi(r3, argcount)
+ ourcode.bne("argserror")
+
+ assert argcount < 9
+
+ if argcount > 0:
+ load_arg(ourcode, 0, signature[0])
+ for i in range(2, argcount):
+ load_arg(ourcode, i, signature[i])
+ if argcount > 1:
+ load_arg(ourcode, 1, signature[1])
+
+ ourcode.bl(FAST_ENTRY_LABEL)
+
+ if retcode == 'i':
+ s = lookup("PyInt_FromLong")
+ ourcode.load_word(r0, s)
+ ourcode.mtctr(r0)
+ ourcode.bctrl()
+ elif retcode == 'f':
+ s = lookup("PyFloat_FromDouble")
+ ourcode.load_word(r0, s)
+ ourcode.mtctr(r0)
+ ourcode.bctrl()
+
+ ourcode.label("epilogue")
+ ourcode.lwz(r0, r1, 88)
+ ourcode.addi(r1, r1, 80)
+ ourcode.mtlr(r0)
+ ourcode.lmw(r31, r1, -4)
+ ourcode.blr()
+
+ err_set = lookup("PyErr_SetObject")
+ exc = lookup("PyExc_TypeError")
+
+ ourcode.label("argserror")
+ ourcode.load_word(r5, err_set)
+ ourcode.mtctr(r5)
+ ourcode.load_from(r3, exc)
+ ourcode.mr(r4, r3)
+ ourcode.bctrl()
+
+ ourcode.li(r3, 0)
+ ourcode.b("epilogue")
+
+ ourcode.label(FAST_ENTRY_LABEL)
+ # err, should be an Assembler method:
+ l = code.labels.copy()
+ for k in l:
+ l[k] += 4*len(ourcode.insts)
+ r = code.rlabels.copy()
+ for k in code.rlabels:
+ r[k + 4*len(ourcode.insts)] = code.rlabels[k]
+ ourcode.insts.extend(code.insts)
+ ourcode.labels.update(l)
+ ourcode.rlabels.update(r)
+
+ r = ourcode.assemble()
+ r.FAST_ENTRY_LABEL = ourcode.labels[FAST_ENTRY_LABEL]
+ return r
+
+def wrap(funcname, retcode, signature):
+
+ argcount = len(signature)
+
+ ourcode = MyPPCAssembler()
+ ourcode.mflr(r0)
+ ourcode.stmw(r31, r1, -4)
+ ourcode.stw(r0, r1, 8)
+ ourcode.stwu(r1, r1, -80)
+
+ ourcode.lwz(r3, r4, 8)
+ ourcode.cmpwi(r3, argcount)
+ ourcode.bne("argserror")
+
+ assert argcount < 9
+
+ if argcount > 0:
+ load_arg(ourcode, 0, signature[0])
+ for i in range(2, argcount):
+ load_arg(ourcode, i, signature[i])
+ if argcount > 1:
+ load_arg(ourcode, 1, signature[1])
+
+
+ ourcode.load_word(r0, lookup(funcname))
+ ourcode.mtctr(r0)
+ ourcode.bctrl()
+
+ if retcode == 'i':
+ s = lookup("PyInt_FromLong")
+ ourcode.load_word(r0, s)
+ ourcode.mtctr(r0)
+ ourcode.bctrl()
+ elif retcode == 'f':
+ s = lookup("PyFloat_FromDouble")
+ ourcode.load_word(r0, s)
+ ourcode.mtctr(r0)
+ ourcode.bctrl()
+
+ ourcode.label("epilogue")
+ ourcode.lwz(r0, r1, 88)
+ ourcode.addi(r1, r1, 80)
+ ourcode.mtlr(r0)
+ ourcode.lmw(r31, r1, -4)
+ ourcode.blr()
+
+ err_set = lookup("PyErr_SetObject")
+ exc = lookup("PyExc_TypeError")
+
+ ourcode.label("argserror")
+ ourcode.load_word(r5, err_set)
+ ourcode.mtctr(r5)
+ ourcode.load_from(r3, exc)
+ ourcode.mr(r4, r3)
+ ourcode.bctrl()
+
+ ourcode.li(r3, 0)
+ ourcode.b("epilogue")
+
+ return ourcode.assemble()
+
Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,788 @@
+import array
+from pypy.translator.asm.ppcgen.ppc_form import PPCForm as Form
+from pypy.translator.asm.ppcgen.ppc_field import ppc_fields
+from pypy.translator.asm.ppcgen.assembler import Assembler
+from pypy.translator.asm.ppcgen.symbol_lookup import lookup
+
+A = Form("frD", "frA", "frB", "XO3", "Rc")
+A1 = Form("frD", "frB", "XO3", "Rc")
+A2 = Form("frD", "frA", "frC", "XO3", "Rc")
+A3 = Form("frD", "frA", "frC", "frB", "XO3", "Rc")
+
+I = Form("LI", "AA", "LK")
+
+B = Form("BO", "BI", "BD", "AA", "LK")
+
+SC = Form("AA") # fudge
+
+DD = Form("rD", "rA", "SIMM")
+DS = Form("rA", "rS", "UIMM")
+
+X = Form("XO1")
+XS = Form("rA", "rS", "rB", "XO1", "Rc")
+XS0 = Form("rS", "rA", "rB", "XO1")
+XD = Form("rD", "rA", "rB", "XO1")
+XO = Form("rD", "rA", "rB", "OE", "XO2", "Rc")
+XO0 = Form("rD", "rA", "OE", "XO2", "Rc")
+XDB = Form("frD", "frB", "XO1", "Rc")
+XS0 = Form("rA", "rS", "XO1", "Rc")
+X0 = Form("rA", "rB", "XO1")
+XcAB = Form("crfD", "rA", "rB", "XO1")
+XN = Form("rD", "rA", "NB", "XO1")
+XL = Form("crbD", "crbA", "crbB", "XO1")
+XL1 = Form("crfD", "crfS")
+XL2 = Form("crbD", "XO1", "Rc")
+XFL = Form("FM", "frB", "XO1", "Rc")
+XFX = Form("CRM", "rS", "XO1")
+
+MI = Form("rS", "rA", "SH", "MB", "ME", "Rc")
+MB = Form("rS", "rA", "rB", "MB", "ME", "Rc")
+
+
+class BasicPPCAssembler(Assembler):
+
+ def disassemble(cls, inst, labels={}, pc=0):
+ cache = cls.__dict__.get('idesc cache')
+ if cache is None:
+ idescs = cls.get_idescs()
+ cache = {}
+ for n, i in idescs:
+ cache.setdefault(i.specializations[ppc_fields['opcode']],
+ []).append((n,i))
+ setattr(cls, 'idesc cache', cache)
+ matches = []
+ idescs = cache[ppc_fields['opcode'].decode(inst)]
+ for name, idesc in idescs:
+ m = idesc.match(inst)
+ if m > 0:
+ matches.append((m, idesc, name))
+ if matches:
+ score, idesc, name = max(matches)
+ return idesc.disassemble(name, inst, labels, pc)
+ disassemble = classmethod(disassemble)
+
+ # "basic" means no simplified mnemonics
+
+ # I form
+ b = I(18, AA=0, LK=0)
+ ba = I(18, AA=1, LK=0)
+ bl = I(18, AA=0, LK=1)
+ bla = I(18, AA=1, LK=1)
+
+ # B form
+ bc = B(16, AA=0, LK=0)
+ bcl = B(16, AA=0, LK=1)
+ bca = B(16, AA=1, LK=0)
+ bcla = B(16, AA=1, LK=1)
+
+ # SC form
+ sc = SC(17, AA=1) # it's not really the aa field...
+
+ # D form
+ addi = DD(14)
+ addic = DD(12)
+ addicx = DD(13)
+ addis = DD(15)
+
+ andix = DS(28)
+ andisx = DS(29)
+
+ cmpi = Form("crfD", "L", "rA", "SIMM")(11)
+ cmpi.default(L=0).default(crfD=0)
+ cmpli = Form("crfD", "L", "rA", "UIMM")(10)
+ cmpli.default(L=0).default(crfD=0)
+
+ lbz = DD(34)
+ lbzu = DD(35)
+ lfd = DD(50)
+ lfdu = DD(51)
+ lfs = DD(48)
+ lfsu = DD(49)
+ lha = DD(42)
+ lhau = DD(43)
+ lhz = DD(40)
+ lhzu = DD(41)
+ lmw = DD(46)
+ lwz = DD(32)
+ lwzu = DD(33)
+
+ mulli = DD(7)
+ ori = DS(24)
+ oris = DS(25)
+
+ stb = DD(38)
+ stbu = DD(39)
+ stfd = DD(54)
+ stfdu = DD(55)
+ stfs = DD(52)
+ stfsu = DD(53)
+ sth = DD(44)
+ sthu = DD(45)
+ stmw = DD(47)
+ stw = DD(36)
+ stwu = DD(37)
+
+ subfic = DD(8)
+ twi = Form("TO", "rA", "SIMM")(3)
+ xori = DS(26)
+ xoris = DS(27)
+
+ # X form
+
+ and_ = XS(31, XO1=28, Rc=0)
+ and_x = XS(31, XO1=28, Rc=1)
+
+ andc_ = XS(31, XO1=60, Rc=0)
+ andc_x = XS(31, XO1=60, Rc=1)
+
+ # is the L bit for 64 bit compares? hmm
+ cmp = Form("crfD", "L", "rA", "rB", "XO1")(31, XO1=0)
+ cmp.default(L=0).default(crfD=0)
+ cmpl = Form("crfD", "L", "rA", "rB", "XO1")(31, XO1=32)
+ cmpl.default(L=0).default(crfD=0)
+
+ cntlzw = XS0(31, XO1=26, Rc=0)
+ cntlzwx = XS0(31, XO1=26, Rc=1)
+
+ dcba = X0(31, XO1=758)
+ dcbf = X0(31, XO1=86)
+ dcbi = X0(31, XO1=470)
+ dcbst = X0(31, XO1=54)
+ dcbt = X0(31, XO1=278)
+ dcbtst = X0(31, XO1=246)
+ dcbz = X0(31, XO1=1014)
+
+ eciwx = XD(31, XO1=310)
+ ecowx = XS(31, XO1=438, Rc=0)
+
+ eieio = X(31, XO1=854)
+
+ eqv = XS(31, XO1=284, Rc=0)
+ eqvx = XS(31, XO1=284, Rc=1)
+
+ extsb = XS0(31, XO1=954, Rc=0)
+ extsbx = XS0(31, XO1=954, Rc=1)
+
+ extsh = XS0(31, XO1=922, Rc=0)
+ extshx = XS0(31, XO1=922, Rc=1)
+
+ fabs = XDB(63, XO1=264, Rc=0)
+ fabsx = XDB(63, XO1=264, Rc=1)
+
+ fcmpo = XcAB(63, XO1=32)
+ fcmpu = XcAB(63, XO1=0)
+
+ fctiw = XDB(63, XO1=14, Rc=0)
+ fctiwx = XDB(63, XO1=14, Rc=1)
+
+ fctiwz = XDB(63, XO1=14, Rc=0)
+ fctiwzx = XDB(63, XO1=14, Rc=1)
+
+ fmr = XDB(63, XO1=72, Rc=0)
+ fmrx = XDB(63, XO1=72, Rc=1)
+
+ fnabs = XDB(63, XO1=136, Rc=0)
+ fnabsx = XDB(63, XO1=136, Rc=1)
+
+ fneg = XDB(63, XO1=40, Rc=0)
+ fnegx = XDB(63, XO1=40, Rc=1)
+
+ frsp = XDB(63, XO1=12, Rc=0)
+ frspx = XDB(63, XO1=12, Rc=1)
+
+ fsqrt = XDB(63, XO1=22, Rc=0)
+
+ icbi = X0(31, XO1=982)
+
+ lbzux = XD(31, XO1=119)
+ lbzx = XD(31, XO1=87)
+ lfdux = XD(31, XO1=631)
+ lfdx = XD(31, XO1=599)
+ lfsux = XD(31, XO1=567)
+ lfsx = XD(31, XO1=535)
+ lhaux = XD(31, XO1=375)
+ lhax = XD(31, XO1=343)
+ lhbrx = XD(31, XO1=790)
+ lhzux = XD(31, XO1=311)
+ lhzx = XD(31, XO1=279)
+ lswi = XD(31, XO1=597)
+ lswx = XD(31, XO1=533)
+ lwarx = XD(31, XO1=20)
+ lwbrx = XD(31, XO1=534)
+ lwzux = XD(31, XO1=55)
+ lwzx = XD(31, XO1=23)
+
+ mcrfs = Form("crfD", "crfS", "XO1")(63, XO1=64)
+ mcrxr = Form("crfD", "XO1")(31, XO1=512)
+ mfcr = Form("rD", "XO1")(31, XO1=19)
+ mffs = Form("frD", "XO1", "Rc")(63, XO1=583, Rc=0)
+ mffsx = Form("frD", "XO1", "Rc")(63, XO1=583, Rc=1)
+ mfmsr = Form("rD", "XO1")(31, XO1=83)
+ mfsr = Form("rD", "SR", "XO1")(31, XO1=595)
+ mfsrin = XDB(31, XO1=659, Rc=0)
+
+ add = XO(31, XO2=266, OE=0, Rc=0)
+ addx = XO(31, XO2=266, OE=0, Rc=1)
+ addo = XO(31, XO2=266, OE=1, Rc=0)
+ addox = XO(31, XO2=266, OE=1, Rc=1)
+
+ addc = XO(31, XO2=10, OE=0, Rc=0)
+ addcx = XO(31, XO2=10, OE=0, Rc=1)
+ addco = XO(31, XO2=10, OE=1, Rc=0)
+ addcox = XO(31, XO2=10, OE=1, Rc=1)
+
+ adde = XO(31, XO2=138, OE=0, Rc=0)
+ addex = XO(31, XO2=138, OE=0, Rc=1)
+ addeo = XO(31, XO2=138, OE=1, Rc=0)
+ addeox = XO(31, XO2=138, OE=1, Rc=1)
+
+ addme = XO(31, rB=0, XO2=234, OE=0, Rc=0)
+ addmex = XO(31, rB=0, XO2=234, OE=0, Rc=1)
+ addmeo = XO(31, rB=0, XO2=234, OE=1, Rc=0)
+ addmeox = XO(31, rB=0, XO2=234, OE=1, Rc=1)
+
+ addze = XO(31, rB=0, XO2=202, OE=0, Rc=0)
+ addzex = XO(31, rB=0, XO2=202, OE=0, Rc=1)
+ addzeo = XO(31, rB=0, XO2=202, OE=1, Rc=0)
+ addzeox = XO(31, rB=0, XO2=202, OE=1, Rc=1)
+
+ bcctr = Form("BO", "BI", "XO1", "LK")(19, XO1=528, LK=0)
+ bcctrl = Form("BO", "BI", "XO1", "LK")(19, XO1=528, LK=1)
+
+ bclr = Form("BO", "BI", "XO1", "LK")(19, XO1=16, LK=0)
+ bclrl = Form("BO", "BI", "XO1", "LK")(19, XO1=16, LK=1)
+
+ crand = XL(19, XO1=257)
+ crandc = XL(19, XO1=129)
+ creqv = XL(19, XO1=289)
+ crnand = XL(19, XO1=225)
+ crnor = XL(19, XO1=33)
+ cror = XL(19, XO1=449)
+ crorc = XL(19, XO1=417)
+ crxor = XL(19, XO1=193)
+
+ divw = XO(31, XO2=491, OE=0, Rc=0)
+ divwx = XO(31, XO2=491, OE=0, Rc=1)
+ divwo = XO(31, XO2=491, OE=1, Rc=0)
+ divwox = XO(31, XO2=491, OE=1, Rc=1)
+
+ divwu = XO(31, XO2=459, OE=0, Rc=0)
+ divwux = XO(31, XO2=459, OE=0, Rc=1)
+ divwuo = XO(31, XO2=459, OE=1, Rc=0)
+ divwuox = XO(31, XO2=459, OE=1, Rc=1)
+
+ fadd = A(63, XO3=21, Rc=0)
+ faddx = A(63, XO3=21, Rc=1)
+ fadds = A(59, XO3=21, Rc=0)
+ faddsx = A(59, XO3=21, Rc=1)
+
+ fdiv = A(63, XO3=18, Rc=0)
+ fdivx = A(63, XO3=18, Rc=1)
+ fdivs = A(59, XO3=18, Rc=0)
+ fdivsx = A(59, XO3=18, Rc=1)
+
+ fmadd = A3(63, XO3=19, Rc=0)
+ fmaddx = A3(63, XO3=19, Rc=1)
+ fmadds = A3(59, XO3=19, Rc=0)
+ fmaddsx = A3(59, XO3=19, Rc=1)
+
+ fmsub = A3(63, XO3=28, Rc=0)
+ fmsubx = A3(63, XO3=28, Rc=1)
+ fmsubs = A3(59, XO3=28, Rc=0)
+ fmsubsx = A3(59, XO3=28, Rc=1)
+
+ fmul = A2(63, XO3=25, Rc=0)
+ fmulx = A2(63, XO3=25, Rc=1)
+ fmuls = A2(59, XO3=25, Rc=0)
+ fmulsx = A2(59, XO3=25, Rc=1)
+
+ fnmadd = A3(63, XO3=31, Rc=0)
+ fnmaddx = A3(63, XO3=31, Rc=1)
+ fnmadds = A3(59, XO3=31, Rc=0)
+ fnmaddsx = A3(59, XO3=31, Rc=1)
+
+ fnmsub = A3(63, XO3=30, Rc=0)
+ fnmsubx = A3(63, XO3=30, Rc=1)
+ fnmsubs = A3(59, XO3=30, Rc=0)
+ fnmsubsx = A3(59, XO3=30, Rc=1)
+
+ fres = A1(59, XO3=24, Rc=0)
+ fresx = A1(59, XO3=24, Rc=1)
+
+ frsp = A1(63, XO3=12, Rc=0)
+ frspx = A1(63, XO3=12, Rc=1)
+
+ frsqrte = A1(63, XO3=26, Rc=0)
+ frsqrtex = A1(63, XO3=26, Rc=1)
+
+ fsel = A3(63, XO3=23, Rc=0)
+ fselx = A3(63, XO3=23, Rc=1)
+
+ frsqrt = A1(63, XO3=22, Rc=0)
+ frsqrtx = A1(63, XO3=22, Rc=1)
+ frsqrts = A1(59, XO3=22, Rc=0)
+ frsqrtsx = A1(59, XO3=22, Rc=1)
+
+ fsub = A(63, XO3=20, Rc=0)
+ fsubx = A(63, XO3=20, Rc=1)
+ fsubs = A(59, XO3=20, Rc=0)
+ fsubsx = A(59, XO3=20, Rc=1)
+
+ isync = X(19, XO1=150)
+
+ mcrf = XL1(19)
+
+ mfspr = Form("rD", "spr", "XO1")(31, XO1=339)
+ mftb = Form("rD", "spr", "XO1")(31, XO1=371)
+
+ mtcrf = XFX(31, XO1=144)
+
+ mtfsb0 = XL2(63, XO1=70, Rc=0)
+ mtfsb0x = XL2(63, XO1=70, Rc=1)
+ mtfsb1 = XL2(63, XO1=38, Rc=0)
+ mtfsb1x = XL2(63, XO1=38, Rc=1)
+
+ mtfsf = XFL(63, XO1=711, Rc=0)
+ mtfsfx = XFL(63, XO1=711, Rc=1)
+
+ mtfsfi = Form("crfD", "IMM", "XO1", "Rc")(63, XO1=134, Rc=0)
+ mtfsfix = Form("crfD", "IMM", "XO1", "Rc")(63, XO1=134, Rc=1)
+
+ mtmsr = Form("rS", "XO1")(31, XO1=146)
+
+ mtspr = Form("rS", "spr", "XO1")(31, XO1=467)
+
+ mtsr = Form("rS", "SR", "XO1")(31, XO1=210)
+ mtsrin = Form("rS", "rB", "XO1")(31, XO1=242)
+
+ mulhw = XO(31, OE=0, XO2=75, Rc=0)
+ mulhwx = XO(31, OE=0, XO2=75, Rc=1)
+
+ mulhwu = XO(31, OE=0, XO2=11, Rc=0)
+ mulhwux = XO(31, OE=0, XO2=11, Rc=1)
+
+ mullw = XO(31, OE=0, XO2=235, Rc=0)
+ mullwx = XO(31, OE=0, XO2=235, Rc=1)
+ mullwo = XO(31, OE=1, XO2=235, Rc=0)
+ mullwox = XO(31, OE=1, XO2=235, Rc=1)
+
+ nand = XS(31, XO1=476, Rc=0)
+ nandx = XS(31, XO1=476, Rc=1)
+
+ neg = XO0(31, OE=0, XO2=104, Rc=0)
+ negx = XO0(31, OE=0, XO2=104, Rc=1)
+ nego = XO0(31, OE=1, XO2=104, Rc=0)
+ negox = XO0(31, OE=1, XO2=104, Rc=1)
+
+ nor = XS(31, XO1=124, Rc=0)
+ norx = XS(31, XO1=124, Rc=1)
+
+ or_ = XS(31, XO1=444, Rc=0)
+ or_x = XS(31, XO1=444, Rc=1)
+
+ orc = XS(31, XO1=412, Rc=0)
+ orcx = XS(31, XO1=412, Rc=1)
+
+ rfi = X(19, XO1=50)
+
+ rlwimi = MI(20, Rc=0)
+ rlwimix = MI(20, Rc=1)
+
+ rlwinm = MI(20, Rc=0)
+ rlwinmx = MI(20, Rc=1)
+
+ rlwnm = MB(23, Rc=0)
+ rlwnmx = MB(23, Rc=1)
+
+ slw = XS(31, XO1=24, Rc=0)
+ slwx = XS(31, XO1=24, Rc=1)
+
+ sraw = XS(31, XO1=792, Rc=0)
+ srawx = XS(31, XO1=792, Rc=1)
+
+ srawi = Form("rA", "rS", "SH", "XO1", "Rc")(31, XO1=824, Rc=0)
+ srawix = Form("rA", "rS", "SH", "XO1", "Rc")(31, XO1=824, Rc=1)
+
+ srw = XS(31, XO1=536, Rc=0)
+ srwx = XS(31, XO1=536, Rc=1)
+
+ stbux = XS0(31, XO1=247)
+ stbx = XS0(31, XO1=215)
+ stfdux = XS0(31, XO1=759)
+ stfdx = XS0(31, XO1=727)
+ stfiwx = XS0(31, XO1=983)
+ stfsux = XS0(31, XO1=695)
+ stfsx = XS0(31, XO1=663)
+ sthbrx = XS0(31, XO1=918)
+ sthux = XS0(31, XO1=439)
+ sthx = XS0(31, XO1=407)
+ stswi = Form("rS", "rA", "NB", "XO1")(31, XO1=725)
+ stswx = XS0(31, XO1=661)
+ stwbrx = XS0(31, XO1=662)
+ stwcxx = Form("rS", "rA", "rB", "XO1", "Rc")(31, XO1=150, Rc=1)
+ stwux = XS0(31, XO1=183)
+ stwx = XS0(31, XO1=151)
+
+ subf = XO(31, XO2=40, OE=0, Rc=0)
+ subfx = XO(31, XO2=40, OE=0, Rc=1)
+ subfo = XO(31, XO2=40, OE=1, Rc=0)
+ subfox = XO(31, XO2=40, OE=1, Rc=1)
+
+ subfc = XO(31, XO2=8, OE=0, Rc=0)
+ subfcx = XO(31, XO2=8, OE=0, Rc=1)
+ subfco = XO(31, XO2=8, OE=1, Rc=0)
+ subfcox = XO(31, XO2=8, OE=1, Rc=1)
+
+ subfe = XO(31, XO2=136, OE=0, Rc=0)
+ subfex = XO(31, XO2=136, OE=0, Rc=1)
+ subfeo = XO(31, XO2=136, OE=1, Rc=0)
+ subfeox = XO(31, XO2=136, OE=1, Rc=1)
+
+ subfme = XO0(31, OE=0, XO2=232, Rc=0)
+ subfmex = XO0(31, OE=0, XO2=232, Rc=1)
+ subfmeo = XO0(31, OE=1, XO2=232, Rc=0)
+ subfmeox= XO0(31, OE=1, XO2=232, Rc=1)
+
+ subfze = XO0(31, OE=0, XO2=200, Rc=0)
+ subfzex = XO0(31, OE=0, XO2=200, Rc=1)
+ subfzeo = XO0(31, OE=1, XO2=200, Rc=0)
+ subfzeox= XO0(31, OE=1, XO2=200, Rc=1)
+
+ sync = X(31, XO1=598)
+
+ tlbia = X(31, XO1=370)
+ tlbie = Form("rB", "XO1")(31, XO1=306)
+ tlbsync = X(31, XO1=566)
+
+ tw = Form("TO", "rA", "rB", "XO1")(31, XO1=4)
+
+ xor = XS(31, XO1=316, Rc=0)
+ xorx = XS(31, XO1=316, Rc=1)
+
+class PPCAssembler(BasicPPCAssembler):
+ BA = BasicPPCAssembler
+
+ # awkward mnemonics:
+ # mftb
+ # most of the branch mnemonics...
+
+ # F.2 Simplified Mnemonics for Subtract Instructions
+
+ def subi(self, rD, rA, value):
+ self.addi(rD, rA, -value)
+ def subis(self, rD, rA, value):
+ self.addis(rD, rA, -value)
+ def subic(self, rD, rA, value):
+ self.addic(rD, rA, -value)
+ def subicx(self, rD, rA, value):
+ self.addicx(rD, rA, -value)
+
+ def sub(self, rD, rA, rB):
+ self.subf(rD, rB, rA)
+ def subc(self, rD, rA, rB):
+ self.subfc(rD, rB, rA)
+ def subx(self, rD, rA, rB):
+ self.subfx(rD, rB, rA)
+ def subcx(self, rD, rA, rB):
+ self.subfcx(rD, rB, rA)
+ def subo(self, rD, rA, rB):
+ self.subfo(rD, rB, rA)
+ def subco(self, rD, rA, rB):
+ self.subfco(rD, rB, rA)
+ def subox(self, rD, rA, rB):
+ self.subfox(rD, rB, rA)
+ def subcox(self, rD, rA, rB):
+ self.subfcox(rD, rB, rA)
+
+ # F.3 Simplified Mnemonics for Compare Instructions
+
+ cmpwi = BA.cmpi(L=0)
+ cmplwi = BA.cmpli(L=0)
+ cmpw = BA.cmp(L=0)
+ cmplw = BA.cmpl(L=0)
+
+ # what's the point?
+
+ # F.4 Simplified Mnemonics for Rotate and Shift Instructions
+
+
+
+ # F.5 Simplified Mnemonics for Branch Instructions
+
+ # there's a lot of these!
+ bt = BA.bc(BO=12)
+ bf = BA.bc(BO=4)
+ bdnz = BA.bc(BO=16, BI=0)
+ bdnzt = BA.bc(BO=8)
+ bdnzf = BA.bc(BO=0)
+ bdz = BA.bc(BO=18)
+ bdzt = BA.bc(BO=10)
+ bdzf = BA.bc(BO=2)
+
+ bta = BA.bca(BO=12)
+ bfa = BA.bca(BO=4)
+ bdnza = BA.bca(BO=16, BI=0)
+ bdnzta = BA.bca(BO=8)
+ bdnzfa = BA.bca(BO=0)
+ bdza = BA.bca(BO=18)
+ bdzta = BA.bca(BO=10)
+ bdzfa = BA.bca(BO=2)
+
+ btl = BA.bcl(BO=12)
+ bfl = BA.bcl(BO=4)
+ bdnzl = BA.bcl(BO=16, BI=0)
+ bdnztl = BA.bcl(BO=8)
+ bdnzfl = BA.bcl(BO=0)
+ bdzl = BA.bcl(BO=18)
+ bdztl = BA.bcl(BO=10)
+ bdzfl = BA.bcl(BO=2)
+
+ btla = BA.bcla(BO=12)
+ bfla = BA.bcla(BO=4)
+ bdnzla = BA.bcla(BO=16, BI=0)
+ bdnztla = BA.bcla(BO=8)
+ bdnzfla = BA.bcla(BO=0)
+ bdzla = BA.bcla(BO=18)
+ bdztla = BA.bcla(BO=10)
+ bdzfla = BA.bcla(BO=2)
+
+ blr = BA.bclr(BO=20, BI=0)
+ btlr = BA.bclr(BO=12)
+ bflr = BA.bclr(BO=4)
+ bdnzlr = BA.bclr(BO=16, BI=0)
+ bdnztlr = BA.bclr(BO=8)
+ bdnzflr = BA.bclr(BO=0)
+ bdzlr = BA.bclr(BO=18, BI=0)
+ bdztlr = BA.bclr(BO=10)
+ bdzflr = BA.bclr(BO=2)
+
+ bctr = BA.bcctr(BO=20, BI=0)
+ btctr = BA.bcctr(BO=12)
+ bfctr = BA.bcctr(BO=4)
+
+ blrl = BA.bclrl(BO=20, BI=0)
+ btlrl = BA.bclrl(BO=12)
+ bflrl = BA.bclrl(BO=4)
+ bdnzlrl = BA.bclrl(BO=16, BI=0)
+ bdnztlrl = BA.bclrl(BO=8)
+ bdnzflrl = BA.bclrl(BO=0)
+ bdzlrl = BA.bclrl(BO=18, BI=0)
+ bdztlrl = BA.bclrl(BO=10)
+ bdzflrl = BA.bclrl(BO=2)
+
+ bctrl = BA.bcctrl(BO=20, BI=0)
+ btctrl = BA.bcctrl(BO=12)
+ bfctrl = BA.bcctrl(BO=4)
+
+ # these should/could take a[n optional] crf argument, but it's a
+ # bit hard to see how to arrange that.
+
+ blt = BA.bc(BO=12, BI=0)
+ ble = BA.bc(BO=4, BI=1)
+ beq = BA.bc(BO=12, BI=2)
+ bge = BA.bc(BO=4, BI=0)
+ bgt = BA.bc(BO=12, BI=1)
+ bnl = BA.bc(BO=4, BI=0)
+ bne = BA.bc(BO=4, BI=2)
+ bng = BA.bc(BO=4, BI=1)
+ bso = BA.bc(BO=12, BI=3)
+ bns = BA.bc(BO=4, BI=3)
+ bun = BA.bc(BO=12, BI=3)
+ bnu = BA.bc(BO=4, BI=3)
+
+ blta = BA.bca(BO=12, BI=0)
+ blea = BA.bca(BO=4, BI=1)
+ beqa = BA.bca(BO=12, BI=2)
+ bgea = BA.bca(BO=4, BI=0)
+ bgta = BA.bca(BO=12, BI=1)
+ bnla = BA.bca(BO=4, BI=0)
+ bnea = BA.bca(BO=4, BI=2)
+ bnga = BA.bca(BO=4, BI=1)
+ bsoa = BA.bca(BO=12, BI=3)
+ bnsa = BA.bca(BO=4, BI=3)
+ buna = BA.bca(BO=12, BI=3)
+ bnua = BA.bca(BO=4, BI=3)
+
+ bltl = BA.bcl(BO=12, BI=0)
+ blel = BA.bcl(BO=4, BI=1)
+ beql = BA.bcl(BO=12, BI=2)
+ bgel = BA.bcl(BO=4, BI=0)
+ bgtl = BA.bcl(BO=12, BI=1)
+ bnll = BA.bcl(BO=4, BI=0)
+ bnel = BA.bcl(BO=4, BI=2)
+ bngl = BA.bcl(BO=4, BI=1)
+ bsol = BA.bcl(BO=12, BI=3)
+ bnsl = BA.bcl(BO=4, BI=3)
+ bunl = BA.bcl(BO=12, BI=3)
+ bnul = BA.bcl(BO=4, BI=3)
+
+ bltla = BA.bcla(BO=12, BI=0)
+ blela = BA.bcla(BO=4, BI=1)
+ beqla = BA.bcla(BO=12, BI=2)
+ bgela = BA.bcla(BO=4, BI=0)
+ bgtla = BA.bcla(BO=12, BI=1)
+ bnlla = BA.bcla(BO=4, BI=0)
+ bnela = BA.bcla(BO=4, BI=2)
+ bngla = BA.bcla(BO=4, BI=1)
+ bsola = BA.bcla(BO=12, BI=3)
+ bnsla = BA.bcla(BO=4, BI=3)
+ bunla = BA.bcla(BO=12, BI=3)
+ bnula = BA.bcla(BO=4, BI=3)
+
+ bltlr = BA.bclr(BO=12, BI=0)
+ blelr = BA.bclr(BO=4, BI=1)
+ beqlr = BA.bclr(BO=12, BI=2)
+ bgelr = BA.bclr(BO=4, BI=0)
+ bgtlr = BA.bclr(BO=12, BI=1)
+ bnllr = BA.bclr(BO=4, BI=0)
+ bnelr = BA.bclr(BO=4, BI=2)
+ bnglr = BA.bclr(BO=4, BI=1)
+ bsolr = BA.bclr(BO=12, BI=3)
+ bnslr = BA.bclr(BO=4, BI=3)
+ bunlr = BA.bclr(BO=12, BI=3)
+ bnulr = BA.bclr(BO=4, BI=3)
+
+ bltctr = BA.bcctr(BO=12, BI=0)
+ blectr = BA.bcctr(BO=4, BI=1)
+ beqctr = BA.bcctr(BO=12, BI=2)
+ bgectr = BA.bcctr(BO=4, BI=0)
+ bgtctr = BA.bcctr(BO=12, BI=1)
+ bnlctr = BA.bcctr(BO=4, BI=0)
+ bnectr = BA.bcctr(BO=4, BI=2)
+ bngctr = BA.bcctr(BO=4, BI=1)
+ bsoctr = BA.bcctr(BO=12, BI=3)
+ bnsctr = BA.bcctr(BO=4, BI=3)
+ bunctr = BA.bcctr(BO=12, BI=3)
+ bnuctr = BA.bcctr(BO=4, BI=3)
+
+ bltlrl = BA.bclrl(BO=12, BI=0)
+ blelrl = BA.bclrl(BO=4, BI=1)
+ beqlrl = BA.bclrl(BO=12, BI=2)
+ bgelrl = BA.bclrl(BO=4, BI=0)
+ bgtlrl = BA.bclrl(BO=12, BI=1)
+ bnllrl = BA.bclrl(BO=4, BI=0)
+ bnelrl = BA.bclrl(BO=4, BI=2)
+ bnglrl = BA.bclrl(BO=4, BI=1)
+ bsolrl = BA.bclrl(BO=12, BI=3)
+ bnslrl = BA.bclrl(BO=4, BI=3)
+ bunlrl = BA.bclrl(BO=12, BI=3)
+ bnulrl = BA.bclrl(BO=4, BI=3)
+
+ bltctrl = BA.bcctrl(BO=12, BI=0)
+ blectrl = BA.bcctrl(BO=4, BI=1)
+ beqctrl = BA.bcctrl(BO=12, BI=2)
+ bgectrl = BA.bcctrl(BO=4, BI=0)
+ bgtctrl = BA.bcctrl(BO=12, BI=1)
+ bnlctrl = BA.bcctrl(BO=4, BI=0)
+ bnectrl = BA.bcctrl(BO=4, BI=2)
+ bngctrl = BA.bcctrl(BO=4, BI=1)
+ bsoctrl = BA.bcctrl(BO=12, BI=3)
+ bnsctrl = BA.bcctrl(BO=4, BI=3)
+ bunctrl = BA.bcctrl(BO=12, BI=3)
+ bnuctrl = BA.bcctrl(BO=4, BI=3)
+
+ # whew! and we haven't even begun the predicted versions...
+
+ # F.6 Simplified Mnemonics for Condition Register
+ # Logical Instructions
+
+ crset = BA.creqv(crbA="crbD", crbB="crbD")
+ crclr = BA.crxor(crbA="crbD", crbB="crbD")
+ cmove = BA.cror(crbA="crbB")
+ crnot = BA.crnor(crbA="crbB")
+
+ # F.7 Simplified Mnemonics for Trap Instructions
+
+ # these can wait!
+
+ # F.8 Simplified Mnemonics for Special-Purpose
+ # Registers
+
+ mfctr = BA.mfspr(spr=9)
+ mflr = BA.mfspr(spr=8)
+ mftbl = BA.mftb(spr=268)
+ mftbu = BA.mftb(spr=269)
+ mfxer = BA.mfspr(spr=1)
+
+ mtctr = BA.mtspr(spr=9)
+ mtlr = BA.mtspr(spr=8)
+ mtxer = BA.mtspr(spr=1)
+
+
+ # F.9 Recommended Simplified Mnemonics
+ nop = BA.ori(rS=0, rA=0, UIMM=0)
+
+ li = BA.addi(rA=0)
+ lis = BA.addis(rA=0)
+
+ mr = BA.or_(rB="rS")
+ mrx = BA.or_x(rB="rS")
+
+ not_ = BA.nor(rB="rS")
+ not_x = BA.norx(rB="rS")
+
+ mtcr = BA.mtcrf(CRM=0xFF)
+
+def hi(w):
+ return w >> 16
+
+def ha(w):
+ if (w >> 15) & 1:
+ return w >> 16 + 1
+ else:
+ return w >> 16
+
+def lo(w):
+ return w & 0x0000FFFF
+
+class MyPPCAssembler(PPCAssembler):
+ def load_word(self, rD, word):
+ self.addis(rD, r0, hi(word))
+ self.ori(rD, rD, lo(word))
+ def load_from(self, rD, addr):
+ self.addis(rD, r0, ha(addr))
+ self.lwz(rD, rD, lo(addr))
+
+def b(n):
+ r = []
+ for i in range(32):
+ r.append(n&1)
+ n >>= 1
+ r.reverse()
+ return ''.join(map(str, r))
+
+from pypy.translator.asm.ppcgen.regname import *
+
+def main():
+
+ a = MyPPCAssembler()
+
+ a.lwz(r5, r4, 12)
+ a.lwz(r6, r4, 16)
+ a.lwz(r7, r5, 8)
+ a.lwz(r8, r6, 8)
+ a.add(r3, r7, r8)
+ a.load_word(r4, lookup("PyInt_FromLong"))
+ a.mtctr(r4)
+ a.bctr()
+
+ f = a.assemble(True)
+ print f(12,3)
+
+ a = MyPPCAssembler()
+ a.label("loop")
+ a.mftbu(r3)
+ a.mftbl(r4)
+ a.mftbu(r5)
+ a.cmpw(r5, r3)
+ a.bne(-16)
+ a.load_word(r5, lookup("PyLong_FromUnsignedLongLong"))
+ a.mtctr(r5)
+ a.bctr()
+
+ tb = a.assemble(True)
+ t0 = tb()
+ print [tb() - t0 for i in range(10)]
+
+if __name__ == '__main__':
+ main()
Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,91 @@
+from pypy.translator.asm.ppcgen.field import Field
+from pypy.translator.asm.ppcgen import regname
+
+fields = { # bit margins are *inclusive*! (and bit 0 is
+ # most-significant, 31 least significant)
+ "opcode": ( 0, 5),
+ "AA": (30, 30),
+ "BD": (16, 29, 'signed'),
+ "BI": (11, 15),
+ "BO": ( 6, 10),
+ "crbA": (11, 15),
+ "crbB": (16, 20),
+ "crbD": ( 6, 10),
+ "crfD": ( 6, 8),
+ "crfS": (11, 13),
+ "CRM": (12, 19),
+ "d": (16, 31, 'signed'),
+ "FM": ( 7, 14),
+ "frA": (11, 15, 'unsigned', regname._F),
+ "frB": (16, 20, 'unsigned', regname._F),
+ "frC": (21, 25, 'unsigned', regname._F),
+ "frD": ( 6, 10, 'unsigned', regname._F),
+ "frS": ( 6, 10, 'unsigned', regname._F),
+ "IMM": (16, 19),
+ "L": (10, 10),
+ "LI": ( 6, 29, 'signed'),
+ "LK": (31, 31),
+ "MB": (21, 25),
+ "ME": (26, 30),
+ "NB": (16, 20),
+ "OE": (21, 21),
+ "rA": (11, 15, 'unsigned', regname._R),
+ "rB": (16, 20, 'unsigned', regname._R),
+ "Rc": (31, 31),
+ "rD": ( 6, 10, 'unsigned', regname._R),
+ "rS": ( 6, 10, 'unsigned', regname._R),
+ "SH": (16, 20),
+ "SIMM": (16, 31, 'signed'),
+ "SR": (12, 15),
+ "spr": (11, 20),
+ "TO": ( 6, 10),
+ "UIMM": (16, 31),
+ "XO1": (21, 30),
+ "XO2": (22, 30),
+ "XO3": (26, 30),
+}
+
+
+class IField(Field):
+ def __init__(self, name, left, right, signedness):
+ assert signedness == 'signed'
+ super(IField, self).__init__(name, left, right, signedness)
+ def encode(self, value):
+ # XXX should check range
+ value &= self.mask << 2 | 0x3
+ return value & ~0x3
+ def decode(self, inst):
+ mask = self.mask << 2
+ v = inst & mask
+ if self.signed and (~mask >> 1) & mask & v:
+ return ~(~v&self.mask)
+ else:
+ return v
+ def r(self, i, labels, pc):
+ if not ppc_fields['AA'].decode(i):
+ v = self.decode(i)
+ if pc+v in labels:
+ return "%s (%r)"%(v, ', '.join(labels[pc+v]))
+ else:
+ return self.decode(i)
+
+
+class spr(Field):
+ def encode(self, value):
+ value = (value&31) << 5 | (value >> 5 & 31)
+ return super(spr, self).encode(value)
+ def decode(self, inst):
+ value = super(spr, self).decode(inst)
+ return (value&31) << 5 | (value >> 5 & 31)
+
+# other special fields?
+
+ppc_fields = {
+ "LI": IField("LI", *fields["LI"]),
+ "BD": IField("BD", *fields["BD"]),
+ "spr": spr("spr", *fields["spr"]),
+}
+
+for f in fields:
+ if f not in ppc_fields:
+ ppc_fields[f] = Field(f, *fields[f])
Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,13 @@
+from pypy.translator.asm.ppcgen.form import Form
+from pypy.translator.asm.ppcgen.ppc_field import ppc_fields
+
+class PPCForm(Form):
+ fieldmap = ppc_fields
+
+ def __init__(self, *fnames):
+ super(PPCForm, self).__init__(*("opcode",) + fnames)
+
+ def __call__(self, opcode, **specializations):
+ specializations['opcode'] = opcode
+ return super(PPCForm, self).__call__(**specializations)
+
Added: pypy/dist/pypy/translator/asm/ppcgen/pystructs.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/pystructs.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,22 @@
+class PyVarObject(object):
+ ob_size = 8
+
+class PyObject(object):
+ ob_refcnt = 0
+ ob_type = 4
+
+class PyTupleObject(object):
+ ob_item = 12
+
+class PyTypeObject(object):
+ tp_name = 12
+ tp_basicsize = 16
+ tp_itemsize = 20
+ tp_dealloc = 24
+
+class PyFloatObject(object):
+ ob_fval = 8
+
+class PyIntObject(object):
+ ob_ival = 8
+
Added: pypy/dist/pypy/translator/asm/ppcgen/regname.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/regname.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,18 @@
+class _R(int):
+ def __repr__(self):
+ return "r%s"%(super(_R, self).__repr__(),)
+ __str__ = __repr__
+class _F(int):
+ def __repr__(self):
+ return "fr%s"%(super(_F, self).__repr__(),)
+ __str__ = __repr__
+
+r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, \
+ r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, \
+ r23, r24, r25, r26, r27, r28, r29, r30, r31 = map(_R, range(32))
+
+fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7, fr8, fr9, fr10, fr11, fr12, \
+ fr13, fr14, fr15, fr16, fr17, fr18, fr19, fr20, fr21, fr22, \
+ fr23, fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31 = map(_F, range(32))
+
+crf0, crf1, crf2, crf3, crf4, crf5, crf6, crf7 = range(8)
Added: pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,11 @@
+import py
+
+_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule()
+
+try:
+ from _ppcgen import NSLookupAndBindSymbol
+
+ def lookup(sym):
+ return NSLookupAndBindSymbol('_' + sym)
+except ImportError:
+ from _ppcgen import dlsym as lookup
Added: pypy/dist/pypy/translator/asm/ppcgen/test/__init__.py
==============================================================================
Added: pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,120 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories don't have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.realpath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ break
+ else:
+ raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+
+ checkpaths = sys.path[:]
+ pypy_root = os.path.join(head, '')
+
+ while checkpaths:
+ orig = checkpaths.pop()
+ fullorig = os.path.join(os.path.realpath(orig), '')
+ if fullorig.startswith(pypy_root):
+ if os.path.exists(os.path.join(fullorig, '__init__.py')):
+ sys.path.remove(orig)
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+
+ munged = {}
+ for name, mod in sys.modules.items():
+ fn = getattr(mod, '__file__', None)
+ if '.' in name or not isinstance(fn, str):
+ continue
+ newname = os.path.splitext(os.path.basename(fn))[0]
+ if not newname.startswith(part + '.'):
+ continue
+ path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+ if path.startswith(pypy_root) and newname != part:
+ modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+ if newname != '__init__':
+ modpaths.append(newname)
+ modpath = '.'.join(modpaths)
+ if modpath not in sys.modules:
+ munged[modpath] = mod
+
+ for name, mod in munged.iteritems():
+ if name not in sys.modules:
+ sys.modules[name] = mod
+ if '.' in name:
+ prename = name[:name.rfind('.')]
+ postname = name[len(prename)+1:]
+ if prename not in sys.modules:
+ __import__(prename)
+ if not hasattr(sys.modules[prename], postname):
+ setattr(sys.modules[prename], postname, mod)
+
+ return partdir, this_dir
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,65 @@
+import autopath
+
+from pypy.translator.asm.ppcgen.field import Field
+from py.test import raises
+
+import random
+import sys
+
+class TestFields(object):
+ def test_decode(self):
+ # this test is crappy
+ field = Field("test", 0, 31)
+ for i in range(100):
+ j = random.randrange(sys.maxint)
+ assert field.decode(j) == j
+ field = Field("test", 0, 31-4)
+ for i in range(100):
+ j = random.randrange(sys.maxint)
+ assert field.decode(j) == j>>4
+ assert field.decode(j) == j>>4
+ field = Field("test", 3, 31-4)
+ for i in range(100):
+ j = random.randrange(sys.maxint>>3)
+ assert field.decode(j) == j>>4
+
+
+ def test_decode_unsigned(self):
+ field = Field("test", 16, 31)
+ for i in range(1000):
+ hi = long(random.randrange(0x10000)) << 16
+ lo = long(random.randrange(0x10000))
+ assert field.decode(hi|lo) == lo
+
+
+ def test_decode_signed(self):
+ field = Field("test", 16, 31, 'signed')
+ for i in range(1000):
+ hi = long(random.randrange(0x10000)) << 16
+ lo = long(random.randrange(0x10000))
+ word = hi|lo
+ if lo & 0x8000:
+ lo |= ~0xFFFF
+ assert field.decode(word) == lo
+
+
+ def test_error_checking_unsigned(self):
+ for b in range(0, 17):
+ field = Field("test", b, 15+b)
+ assert field.decode(field.encode(0)) == 0
+ assert field.decode(field.encode(32768)) == 32768
+ assert field.decode(field.encode(65535)) == 65535
+ raises(ValueError, field.encode, -32768)
+ raises(ValueError, field.encode, -1)
+ raises(ValueError, field.encode, 65536)
+
+
+ def test_error_checking_signed(self):
+ for b in range(0, 17):
+ field = Field("test", b, 15+b, 'signed')
+ assert field.decode(field.encode(0)) == 0
+ assert field.decode(field.encode(-32768)) == -32768
+ assert field.decode(field.encode(32767)) == 32767
+ raises(ValueError, field.encode, 32768)
+ raises(ValueError, field.encode, -32769)
+
Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,69 @@
+import autopath
+from pypy.translator.asm.ppcgen.ppc_assembler import b
+import unittest
+import random
+import sys
+
+from pypy.translator.asm.ppcgen.form import Form, FormException
+from pypy.translator.asm.ppcgen.field import Field
+from pypy.translator.asm.ppcgen.assembler import Assembler
+
+# 0 31
+# +-------------------------------+
+# | h | l |
+# +-------------------------------+
+# | hh | hl | lh | ll |
+# +-------------------------------+
+
+test_fieldmap = {
+ 'l' : Field('l', 16, 31),
+ 'h' : Field('h', 0, 15),
+ 'll': Field('ll', 24, 31),
+ 'lh': Field('lh', 16, 23),
+ 'hl': Field('hl', 8, 15),
+ 'hh': Field('hh', 0, 7),
+}
+
+def p(w):
+ import struct
+ return struct.pack('i', w)
+
+
+class TestForm(Form):
+ fieldmap = test_fieldmap
+
+class TestForms(object):
+ def test_bitclash(self):
+ raises(FormException, TestForm, 'h', 'hh')
+ raises(FormException, TestForm,
+ Field('t1', 0, 0), Field('t2', 0, 0))
+
+ def test_basic(self):
+ class T(Assembler):
+ i = TestForm('h', 'l')()
+ j = i(h=1)
+ k = i(l=3)
+ raises(FormException, k, l=0)
+ a = T()
+ a.i(5, 6)
+ assert p(a.assemble0()[0]) == '\000\005\000\006'
+ a = T()
+ a.j(2)
+ assert p(a.assemble0()[0]) == '\000\001\000\002'
+ a = T()
+ a.k(4)
+ assert p(a.assemble0()[0]) == '\000\004\000\003'
+
+ def test_defdesc(self):
+ class T(Assembler):
+ i = TestForm('hh', 'hl', 'lh', 'll')()
+ i.default(hl=0).default(hh=1)
+ a = T()
+ a.i(1, 2, 3, 4)
+ assert p(a.assemble0()[0]) == '\001\002\003\004'
+ a = T()
+ a.i(1, 3, 4)
+ assert p(a.assemble0()[0]) == '\001\000\003\004'
+ a = T()
+ a.i(3, 4)
+ assert p(a.assemble0()[0]) == '\001\000\003\004'
Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,87 @@
+import unittest
+
+import random, sys, os
+
+from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler
+from pypy.translator.asm.ppcgen.symbol_lookup import lookup
+from pypy.translator.asm.ppcgen.func_builder import make_func
+from pypy.translator.asm.ppcgen import form, func_builder
+from pypy.translator.asm.ppcgen.regname import *
+
+class TestFuncBuilderTest(object):
+ def setup_class(cls):
+ if os.uname()[-1] != 'Power Macintosh':
+ py.test.skip("can't test all of ppcgen on non-PPC!")
+
+ def test_simple(self):
+ a = MyPPCAssembler()
+ a.blr()
+ f = make_func(a, "O", "O")
+ assert f(1) == 1
+ raises(TypeError, f)
+ raises(TypeError, f, 1, 2)
+
+ def test_less_simple(self):
+ a = MyPPCAssembler()
+ s = lookup("PyNumber_Add")
+ a.load_word(r5, s)
+ a.mtctr(r5)
+ a.bctr()
+ f = make_func(a, "O", "OO")
+ raises(TypeError, f)
+ raises(TypeError, f, 1)
+ assert f(1, 2) == 3
+ raises(TypeError, f, 1, 2, 3)
+
+ def test_signature(self):
+ a = MyPPCAssembler()
+ a.add(r3, r3, r4)
+ a.blr()
+ f = make_func(a, "i", "ii")
+ raises(TypeError, f)
+ raises(TypeError, f, 1)
+ assert f(1, 2) == 3
+ raises(TypeError, f, 1, 2, 3)
+ raises(TypeError, f, 1, "2")
+
+ def test_signature2(self):
+ a = MyPPCAssembler()
+ a.add(r3, r3, r4)
+ a.add(r3, r3, r5)
+ a.add(r3, r3, r6)
+ a.add(r3, r3, r7)
+ s = lookup("PyInt_FromLong")
+ a.load_word(r0, s)
+ a.mtctr(r0)
+ a.bctr()
+ f = make_func(a, "O", "iiiii")
+ raises(TypeError, f)
+ raises(TypeError, f, 1)
+ assert f(1, 2, 3, 4, 5) == 1 + 2 + 3 + 4 + 5
+ raises(TypeError, f, 1, 2, 3)
+ raises(TypeError, f, 1, "2", 3, 4, 5)
+
+ def test_floats(self):
+ a = MyPPCAssembler()
+ a.fadd(fr1, fr1, fr2)
+ a.blr()
+ f = make_func(a, 'f', 'ff')
+ raises(TypeError, f)
+ raises(TypeError, f, 1.0)
+ assert f(1.0, 2.0) == 3.0
+ raises(TypeError, f, 1.0, 2.0, 3.0)
+ raises(TypeError, f, 1.0, 2)
+
+ def test_fast_entry(self):
+ a = MyPPCAssembler()
+ a.blr()
+ f = make_func(a, "O", "O")
+ assert f(1) == 1
+ b = MyPPCAssembler()
+ from pypy.translator.asm.ppcgen import util
+ # eurgh!:
+ b.load_word(r0, util.access_at(id(f.code), 8) + f.FAST_ENTRY_LABEL)
+ b.mtctr(r0)
+ b.bctr()
+ g = make_func(b, "O", "O")
+ assert g(1) == 1
Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,191 @@
+import random, sys, os
+
+from pypy.translator.asm.ppcgen.ppc_assembler import BasicPPCAssembler, MyPPCAssembler
+from pypy.translator.asm.ppcgen.symbol_lookup import lookup
+from pypy.translator.asm.ppcgen.regname import *
+from pypy.translator.asm.ppcgen import form, pystructs
+
+
+class TestDisassemble(object):
+ def test_match(self):
+ A = BasicPPCAssembler
+ a = A()
+ a.add(1, 2, 3)
+ inst = a.insts[-1]
+ assert A.add.match(inst.assemble())
+
+
+class TestAssemble(object):
+
+ def setup_class(cls):
+ if os.uname()[-1] != 'Power Macintosh':
+ py.test.skip("can't test all of ppcgen on non-PPC!")
+
+ def test_tuplelength(self):
+ a = MyPPCAssembler()
+
+ a.lwz(3, 4, pystructs.PyVarObject.ob_size)
+ a.load_word(5, lookup("PyInt_FromLong"))
+ a.mtctr(5)
+ a.bctr()
+
+ f = a.assemble()
+ assert f() == 0
+ assert f(1) == 1
+ assert f('') == 1
+
+
+ def test_tuplelength2(self):
+ a = MyPPCAssembler()
+
+ a.mflr(0)
+ a.stw(0, 1, 8)
+ a.stwu(1, 1, -80)
+ a.mr(3, 4)
+ a.load_word(5, lookup("PyTuple_Size"))
+ a.mtctr(5)
+ a.bctrl()
+ a.load_word(5, lookup("PyInt_FromLong"))
+ a.mtctr(5)
+ a.bctrl()
+ a.lwz(0, 1, 88)
+ a.addi(1, 1, 80)
+ a.mtlr(0)
+ a.blr()
+
+ f = a.assemble()
+ assert f() == 0
+ assert f(1) == 1
+ assert f('') == 1
+ assert f('', 3) == 2
+
+
+ def test_intcheck(self):
+ a = MyPPCAssembler()
+
+ a.lwz(r5, r4, pystructs.PyVarObject.ob_size)
+ a.cmpwi(r5, 1)
+ a.bne("not_one")
+ a.lwz(r5, r4, pystructs.PyTupleObject.ob_item + 0*4)
+ a.lwz(r5, r5, 4)
+ a.load_word(r6, lookup("PyInt_Type"))
+ a.cmpw(r5, r6)
+ a.bne("not_int")
+ a.li(r3, 1)
+ a.b("exit")
+ a.label("not_int")
+ a.li(r3, 0)
+ a.b("exit")
+ a.label("not_one")
+ a.li(r3, 2)
+ a.label("exit")
+ a.load_word(r5, lookup("PyInt_FromLong"))
+ a.mtctr(r5)
+ a.bctr()
+
+ f = a.assemble()
+
+ assert f() == 2
+ assert f("", "") == 2
+ assert f("") == 0
+ assert f(1) == 1
+
+
+ def test_raise(self):
+ a = MyPPCAssembler()
+
+ a.mflr(0)
+ a.stw(0, 1, 8)
+ a.stwu(1, 1, -80)
+
+ err_set = lookup("PyErr_SetObject")
+ exc = lookup("PyExc_ValueError")
+
+ a.load_word(5, err_set)
+ a.mtctr(5)
+ a.load_from(3, exc)
+ a.mr(4, 3)
+ a.bctrl()
+
+ a.li(3, 0)
+
+ a.lwz(0, 1, 88)
+ a.addi(1, 1, 80)
+ a.mtlr(0)
+ a.blr()
+
+ raises(ValueError, a.assemble())
+
+
+ def test_makestring(self):
+ a = MyPPCAssembler()
+
+ a.li(r3, 0)
+ a.li(r4, 0)
+ a.load_word(r5, lookup("PyString_FromStringAndSize"))
+ a.mtctr(r5)
+ a.bctr()
+
+ f = a.assemble()
+ assert f() == ''
+
+
+ def test_numberadd(self):
+ a = MyPPCAssembler()
+
+ a.lwz(r5, r4, pystructs.PyVarObject.ob_size)
+ a.cmpwi(r5, 2)
+ a.bne("err_out")
+
+ a.lwz(r3, r4, 12)
+ a.lwz(r4, r4, 16)
+
+ a.load_word(r5, lookup("PyNumber_Add"))
+ a.mtctr(r5)
+ a.bctr()
+
+ a.label("err_out")
+
+ a.mflr(r0)
+ a.stw(r0, r1, 8)
+ a.stwu(r1, r1, -80)
+
+ err_set = lookup("PyErr_SetObject")
+ exc = lookup("PyExc_TypeError")
+
+ a.load_word(r5, err_set)
+ a.mtctr(r5)
+ a.load_from(r3, exc)
+ a.mr(r4, r3)
+ a.bctrl()
+
+ a.li(r3, 0)
+
+ a.lwz(r0, r1, 88)
+ a.addi(r1, r1, 80)
+ a.mtlr(r0)
+ a.blr()
+
+ f = a.assemble()
+
+ raises(TypeError, f)
+ raises(TypeError, f, '', 1)
+ raises(TypeError, f, 1)
+ raises(TypeError, f, 1, 2, 3)
+ assert f(1, 2) == 3
+ assert f('a', 'b') == 'ab'
+
+
+ def test_assemblerChecks(self):
+ def testFailure(idesc, *args):
+ a = MyPPCAssembler()
+ raises(ValueError, idesc.__get__(a), *args)
+ def testSucceed(idesc, *args):
+ a = MyPPCAssembler()
+ # "assertNotRaises" :-)
+ idesc.__get__(a)(*args)
+ testFailure(MyPPCAssembler.add, 32, 31, 30)
+ testFailure(MyPPCAssembler.add, -1, 31, 30)
+ testSucceed(MyPPCAssembler.bne, -12)
+ testSucceed(MyPPCAssembler.lwz, 0, 0, 32767)
+ testSucceed(MyPPCAssembler.lwz, 0, 0, -32768)
Added: pypy/dist/pypy/translator/asm/ppcgen/util.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/ppcgen/util.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,23 @@
+from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler
+from pypy.translator.asm.ppcgen.func_builder import make_func
+
+from regname import *
+
+def access_at():
+ a = MyPPCAssembler()
+
+ a.lwzx(r3, r3, r4)
+ a.blr()
+
+ return make_func(a, "i", "ii")
+
+access_at = access_at()
+
+def itoO():
+ a = MyPPCAssembler()
+
+ a.blr()
+
+ return make_func(a, "O", "i")
+
+itoO = itoO()
Added: pypy/dist/pypy/translator/asm/test/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/test/__init__.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1 @@
+# ppc only for now!!
Added: pypy/dist/pypy/translator/asm/test/autopath.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/test/autopath.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,120 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories don't have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.realpath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ break
+ else:
+ raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+
+ checkpaths = sys.path[:]
+ pypy_root = os.path.join(head, '')
+
+ while checkpaths:
+ orig = checkpaths.pop()
+ fullorig = os.path.join(os.path.realpath(orig), '')
+ if fullorig.startswith(pypy_root):
+ if os.path.exists(os.path.join(fullorig, '__init__.py')):
+ sys.path.remove(orig)
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+
+ munged = {}
+ for name, mod in sys.modules.items():
+ fn = getattr(mod, '__file__', None)
+ if '.' in name or not isinstance(fn, str):
+ continue
+ newname = os.path.splitext(os.path.basename(fn))[0]
+ if not newname.startswith(part + '.'):
+ continue
+ path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+ if path.startswith(pypy_root) and newname != part:
+ modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+ if newname != '__init__':
+ modpaths.append(newname)
+ modpath = '.'.join(modpaths)
+ if modpath not in sys.modules:
+ munged[modpath] = mod
+
+ for name, mod in munged.iteritems():
+ if name not in sys.modules:
+ sys.modules[name] = mod
+ if '.' in name:
+ prename = name[:name.rfind('.')]
+ postname = name[len(prename)+1:]
+ if prename not in sys.modules:
+ __import__(prename)
+ if not hasattr(sys.modules[prename], postname):
+ setattr(sys.modules[prename], postname, mod)
+
+ return partdir, this_dir
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/dist/pypy/translator/asm/test/test_asm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/test/test_asm.py Mon Oct 10 19:49:28 2005
@@ -0,0 +1,48 @@
+from pypy.translator.translator import Translator
+import py
+import os
+
+class TestAsm(object):
+
+ def setup_class(cls):
+ if os.uname()[-1] != 'Power Macintosh':
+ py.test.skip('asm generation only on PPC')
+ cls.processor = 'ppc'
+
+ def getcompiled(self, func, view=False):
+ t = Translator(func, simplifying=True)
+ # builds starting-types from func_defs
+ argstypelist = []
+ if func.func_defaults is None:
+ assert func.func_code.co_argcount == 0
+ argtypes = []
+ else:
+ assert len(func.func_defaults) == func.func_code.co_argcount
+ argtypes = list(func.func_defaults)
+ a = t.annotate(argtypes)
+ a.simplify()
+ t.specialize()
+ t.checkgraphs()
+# t.backend_optimizations()
+ if view:
+ t.view()
+ return t.asmcompile(self.processor)
+
+ def dont_test_trivial(self):
+ def testfn():
+ return None
+ f = self.getcompiled(testfn)
+ assert f() == None
+
+ def test_int_add(self):
+ def testfn(x=int, y=int):
+ z = 1 + x
+ if z > 0:
+ return x + y + z
+ else:
+ return x + y - 42
+ f = self.getcompiled(testfn)#, view=True)
+ assert f(2, 3) == testfn(2, 3)
+ assert f(-2, 3) == testfn(-2, 3)
+
+
Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py
==============================================================================
--- pypy/dist/pypy/translator/tool/pygame/graphdisplay.py (original)
+++ pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Mon Oct 10 19:49:28 2005
@@ -606,7 +606,7 @@
def process_MouseButtonDown(self, event):
self.dragging = self.click_origin = event.pos
self.click_time = time.time()
- pygame.event.set_grab(True)
+# pygame.event.set_grab(True)
def process_MouseButtonUp(self, event):
self.dragging = None
Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py (original)
+++ pypy/dist/pypy/translator/translator.py Mon Oct 10 19:49:28 2005
@@ -327,6 +327,12 @@
self.frozen = True
return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name, gcpolicy=gcpolicy)
+ def asmcompile(self, processor='ppc'):
+ from pypy.translator.asm import genasm
+ assert processor == 'ppc', 'only ppc asm-generation supported for now'
+ assert self.rtyper is not None, 'must specialize'
+ return genasm.genasm(self)
+
def call(self, *args):
"""Calls underlying Python function."""
return self.entrypoint(*args)
More information about the Pypy-commit
mailing list