Commits

Hakan Ardo committed aa8f94d Merge

merge default

  • Participants
  • Parent commits 1fd30ab, 975e3cf
  • Branches jit-usable_retrace_3

Comments (0)

Files changed (44)

lib-python/2.7/ctypes/test/test_internals.py

 # This tests the internal _objects attribute
 import unittest
 from ctypes import *
-from sys import getrefcount as grc
+try:
+    from sys import getrefcount as grc
+except ImportError:
+    grc = None      # e.g. PyPy
 
 # XXX This test must be reviewed for correctness!!!
 
         self.assertEqual(id(a), id(b))
 
     def test_ints(self):
+        if grc is None:
+            return unittest.skip("no sys.getrefcount()")
         i = 42000123
         refcnt = grc(i)
         ci = c_int(i)
         self.assertEqual(ci._objects, None)
 
     def test_c_char_p(self):
+        if grc is None:
+            return unittest.skip("no sys.getrefcount()")
         s = "Hello, World"
         refcnt = grc(s)
         cs = c_char_p(s)

lib-python/2.7/ctypes/test/test_memfunctions.py

         s = string_at("foo bar")
         # XXX The following may be wrong, depending on how Python
         # manages string instances
-        self.assertEqual(2, sys.getrefcount(s))
+        if hasattr(sys, 'getrefcount'):
+            self.assertEqual(2, sys.getrefcount(s))
         self.assertTrue(s, "foo bar")
 
         self.assertEqual(string_at("foo bar", 8), "foo bar\0")

lib-python/2.7/ctypes/test/test_python_api.py

 
 ################################################################
 
-from sys import getrefcount as grc
+try:
+    from sys import getrefcount as grc
+except ImportError:
+    grc = None      # e.g. PyPy
 if sys.version_info > (2, 4):
     c_py_ssize_t = c_size_t
 else:

lib-python/2.7/ctypes/test/test_refcounts.py

 class RefcountTestCase(unittest.TestCase):
 
     def test_1(self):
-        from sys import getrefcount as grc
+        try:
+            from sys import getrefcount as grc
+        except ImportError:
+            return unittest.skip("no sys.getrefcount()")
 
         f = dll._testfunc_callback_i_if
         f.restype = ctypes.c_int
 
 
     def test_refcount(self):
-        from sys import getrefcount as grc
+        try:
+            from sys import getrefcount as grc
+        except ImportError:
+            return unittest.skip("no sys.getrefcount()")
         def func(*args):
             pass
         # this is the standard refcount for func
 class AnotherLeak(unittest.TestCase):
     def test_callback(self):
         import sys
+        try:
+            from sys import getrefcount
+        except ImportError:
+            return unittest.skip("no sys.getrefcount()")
 
         proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)
         def func(a, b):

lib_pypy/_ctypes_test.py

 import tempfile
 import gc
 
-# Monkeypatch & hacks to let ctypes.tests import.
-# This should be removed at some point.
-sys.getrefcount = lambda x: len(gc.get_referrers(x)) - 1
-
 def compile_shared():
     """Compile '_ctypes_test.c' into an extension module, and import it
     """

lib_pypy/numpypy/core/arrayprint.py

                   'int' : IntegerFormat(data),
                   'float' : FloatFormat(data, precision, suppress_small),
                   'longfloat' : LongFloatFormat(precision),
-                  #'complexfloat' : ComplexFormat(data, precision,
-                  #                               suppress_small),
-                  #'longcomplexfloat' : LongComplexFormat(precision),
+                  'complexfloat' : ComplexFormat(data, precision,
+                                                 suppress_small),
+                  'longcomplexfloat' : LongComplexFormat(precision),
                   'datetime' : DatetimeFormat(data),
                   'timedelta' : TimedeltaFormat(data),
                   'numpystr' : repr_format,
             #else:
             format_function = formatdict['int']
         elif issubclass(dtypeobj, _nt.floating):
-            #if issubclass(dtypeobj, _nt.longfloat):
-            #    format_function = formatdict['longfloat']
-            #else:
-            format_function = formatdict['float']
-        #elif issubclass(dtypeobj, _nt.complexfloating):
-        #    if issubclass(dtypeobj, _nt.clongfloat):
-        #        format_function = formatdict['longcomplexfloat']
-        #    else:
-        #        format_function = formatdict['complexfloat']
+            if issubclass(dtypeobj, _nt.longfloat):
+                format_function = formatdict['longfloat']
+            else:
+                format_function = formatdict['float']
+        elif issubclass(dtypeobj, _nt.complexfloating):
+            if issubclass(dtypeobj, _nt.clongfloat):
+                format_function = formatdict['longcomplexfloat']
+            else:
+                format_function = formatdict['complexfloat']
         elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
             format_function = formatdict['numpystr']
-        elif issubclass(dtypeobj, _nt.datetime64):
-            format_function = formatdict['datetime']
+        #elif issubclass(dtypeobj, _nt.datetime64):
+        #    format_function = formatdict['datetime']
         else:
             format_function = formatdict['str']
 

pypy/annotation/binaryop.py

 from pypy.annotation.model import SomeUnicodeCodePoint, SomeUnicodeString
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
-from pypy.annotation.model import SomePBC, SomeFloat, s_None
+from pypy.annotation.model import SomePBC, SomeFloat, s_None, SomeByteArray
 from pypy.annotation.model import SomeExternalObject, SomeWeakRef
 from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess
 from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType
             result.const = str1.const + str2.const
         return result
 
+class __extend__(pairtype(SomeByteArray, SomeByteArray)):
+    def union((b1, b2)):
+        can_be_None = b1.can_be_None or b2.can_be_None
+        return SomeByteArray(can_be_None=can_be_None)
+
+    def add((b1, b2)):
+        result = SomeByteArray()
+        if b1.is_immutable_constant() and b2.is_immutable_constant():
+            result.const = b1.const + b2.const
+        return result
+
+class __extend__(pairtype(SomeByteArray, SomeInteger)):
+    def getitem((s_b, s_i)):
+        return SomeInteger()
+
+    def setitem((s_b, s_i), s_i2):
+        assert isinstance(s_i2, SomeInteger)
+
+class __extend__(pairtype(SomeString, SomeByteArray),
+                 pairtype(SomeByteArray, SomeString),
+                 pairtype(SomeChar, SomeByteArray),
+                 pairtype(SomeByteArray, SomeChar)):
+    def add((b1, b2)):
+        result = SomeByteArray()
+        if b1.is_immutable_constant() and b2.is_immutable_constant():
+            result.const = b1.const + b2.const
+        return result
+
 class __extend__(pairtype(SomeChar, SomeChar)):
 
     def union((chr1, chr2)):

pypy/annotation/bookkeeper.py

      SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \
      SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \
      SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \
-     SomeWeakRef, lltype_to_annotation, SomeType
+     SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray
 from pypy.annotation.classdef import InstanceSource, ClassDef
 from pypy.annotation.listdef import ListDef, ListItem
 from pypy.annotation.dictdef import DictDef
                 result = SomeUnicodeCodePoint()
             else:
                 result = SomeUnicodeString()
+        elif tp is bytearray:
+            result = SomeByteArray()
         elif tp is tuple:
             result = SomeTuple(items = [self.immutablevalue(e, need_const) for e in x])
         elif tp is float:

pypy/annotation/builtin.py

 from pypy.annotation.model import SomeFloat, unionof, SomeUnicodeString
 from pypy.annotation.model import SomePBC, SomeInstance, SomeDict, SomeList
 from pypy.annotation.model import SomeWeakRef, SomeIterator
-from pypy.annotation.model import SomeOOObject
+from pypy.annotation.model import SomeOOObject, SomeByteArray
 from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation, ll_to_annotation
 from pypy.annotation.model import add_knowntypedata
 from pypy.annotation.model import s_ImpossibleValue
 def builtin_unicode(s_unicode):
     return constpropagate(unicode, [s_unicode], SomeUnicodeString())
 
+def builtin_bytearray(s_str):
+    return constpropagate(bytearray, [s_str], SomeByteArray())
+
 def our_issubclass(cls1, cls2):
     """ we're going to try to be less silly in the face of old-style classes"""
     from pypy.annotation.classdef import ClassDef
                 s = SomeInteger(nonneg=True, knowntype=s.knowntype)
         return s
 
-def builtin_apply(*stuff):
-    getbookkeeper().warning("ignoring apply%r" % (stuff,))
-    return SomeObject()
-
-##def builtin_slice(*args):
-##    bk = getbookkeeper()
-##    if len(args) == 1:
-##        return SomeSlice(
-##            bk.immutablevalue(None), args[0], bk.immutablevalue(None))
-##    elif len(args) == 2:
-##        return SomeSlice(
-##            args[0], args[1], bk.immutablevalue(None))
-##    elif len(args) == 3:
-##        return SomeSlice(
-##            args[0], args[1], args[2])
-##    else:
-##        raise Exception, "bogus call to slice()"
-
 
 def OSError_init(s_self, *args):
     pass

pypy/annotation/model.py

     "Stands for an object which is known to be an unicode string"
     knowntype = unicode
 
+class SomeByteArray(SomeStringOrUnicode):
+    knowntype = bytearray
+
 class SomeChar(SomeString):
     "Stands for an object known to be a string of length 1."
     can_be_None = False

pypy/annotation/test/test_annrpython.py

         a = self.RPythonAnnotator()
         a.build_types(f, []) # assert did not explode
 
+    def test_bytearray(self):
+        def f():
+            return bytearray("xyz")
+
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, []), annmodel.SomeByteArray)
+
+    def test_bytearray_add(self):
+        def f(a):
+            return a + bytearray("xyz")
+
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, [annmodel.SomeByteArray()]),
+                          annmodel.SomeByteArray)
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, [str]),
+                          annmodel.SomeByteArray)
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, [annmodel.SomeChar()]),
+                          annmodel.SomeByteArray)
+
+    def test_bytearray_setitem_getitem(self):
+        def f(b, i, c):
+            b[i] = c
+            return b[i + 1]
+
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, [annmodel.SomeByteArray(),
+                                            int, int]),
+                          annmodel.SomeInteger)
+
 def g(n):
     return [0,1,2,n]
 

pypy/jit/backend/arm/assembler.py

 from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
 from pypy.jit.backend.arm.locations import get_fp_offset
 from pypy.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager,
-                    ARMv7RegisterManager, check_imm_arg,
+                    CoreRegisterManager, check_imm_arg,
                     operations as regalloc_operations,
                     operations_with_guard as regalloc_operations_with_guard)
 from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
             # are stored in r0 and r1.
             mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value)
             addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
-            for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
+            for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
                 mc.STR_ri(reg.value, r.fp.value, imm=ofs)
             mc.BL(addr)
-            for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
+            for reg, ofs in CoreRegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
                 mc.LDR_ri(reg.value, r.fp.value, imm=ofs)
 
         mc.CMP_ri(r.r0.value, 0)

pypy/jit/backend/arm/helper/regalloc.py

         imm_a0 = check_imm_box(a0, imm_size, allow_zero=allow_zero)
         imm_a1 = check_imm_box(a1, imm_size, allow_zero=allow_zero)
         if not imm_a0 and imm_a1:
-            l0 = self._ensure_value_is_boxed(a0)
+            l0 = self.make_sure_var_in_reg(a0)
             l1 = self.convert_to_imm(a1)
         elif commutative and imm_a0 and not imm_a1:
             l1 = self.convert_to_imm(a0)
-            l0 = self._ensure_value_is_boxed(a1, boxes)
+            l0 = self.make_sure_var_in_reg(a1, boxes)
         else:
-            l0 = self._ensure_value_is_boxed(a0, boxes)
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         res = self.force_allocate_reg(op.result, boxes)
     if guard:
         def f(self, op, guard_op, fcond):
             locs = []
-            loc1 = self._ensure_value_is_boxed(op.getarg(0))
+            loc1 = self.make_sure_var_in_reg(op.getarg(0))
             locs.append(loc1)
             if base:
-                loc2 = self._ensure_value_is_boxed(op.getarg(1))
+                loc2 = self.make_sure_var_in_reg(op.getarg(1))
                 locs.append(loc2)
             self.possibly_free_vars_for_op(op)
             self.free_temp_vars()
     else:
         def f(self, op, fcond):
             locs = []
-            loc1 = self._ensure_value_is_boxed(op.getarg(0))
+            loc1 = self.make_sure_var_in_reg(op.getarg(0))
             locs.append(loc1)
             if base:
-                loc2 = self._ensure_value_is_boxed(op.getarg(1))
+                loc2 = self.make_sure_var_in_reg(op.getarg(1))
                 locs.append(loc2)
             self.possibly_free_vars_for_op(op)
             self.free_temp_vars()
         arg0, arg1 = boxes
         imm_a1 = check_imm_box(arg1)
 
-        l0 = self._ensure_value_is_boxed(arg0, forbidden_vars=boxes)
+        l0 = self.make_sure_var_in_reg(arg0, forbidden_vars=boxes)
         if imm_a1:
             l1 = self.convert_to_imm(arg1)
         else:
-            l1 = self._ensure_value_is_boxed(arg1, forbidden_vars=boxes)
+            l1 = self.make_sure_var_in_reg(arg1, forbidden_vars=boxes)
 
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         assert fcond is not None
         a0 = op.getarg(0)
         assert isinstance(a0, Box)
-        reg = self._ensure_value_is_boxed(a0)
+        reg = self.make_sure_var_in_reg(a0)
         self.possibly_free_vars_for_op(op)
         if guard_op is None:
             res = self.force_allocate_reg(op.result, [a0])

pypy/jit/backend/arm/opassembler.py

     def _emit_copystrcontent(self, op, regalloc, fcond, is_unicode):
         # compute the source address
         args = op.getarglist()
-        base_loc = regalloc._ensure_value_is_boxed(args[0], args)
-        ofs_loc = regalloc._ensure_value_is_boxed(args[2], args)
+        base_loc = regalloc.make_sure_var_in_reg(args[0], args)
+        ofs_loc = regalloc.make_sure_var_in_reg(args[2], args)
         assert args[0] is not args[1]    # forbidden case of aliasing
         regalloc.possibly_free_var(args[0])
         regalloc.free_temp_vars()
         dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box,
                                                         selected_reg=r.r0)
         forbidden_vars.append(dstaddr_box)
-        base_loc = regalloc._ensure_value_is_boxed(args[1], forbidden_vars)
-        ofs_loc = regalloc._ensure_value_is_boxed(args[3], forbidden_vars)
+        base_loc = regalloc.make_sure_var_in_reg(args[1], forbidden_vars)
+        ofs_loc = regalloc.make_sure_var_in_reg(args[3], forbidden_vars)
         assert base_loc.is_reg()
         assert ofs_loc.is_reg()
         regalloc.possibly_free_var(args[1])
         # need the box here
         if isinstance(args[4], Box):
             length_box = args[4]
-            length_loc = regalloc._ensure_value_is_boxed(args[4],
+            length_loc = regalloc.make_sure_var_in_reg(args[4],
                                                         forbidden_vars)
         else:
             length_box = TempInt()

pypy/jit/backend/arm/regalloc.py

 def void(self, op, fcond):
     return []
 
+class ARMRegisterManager(RegisterManager):
+    def return_constant(self, v, forbidden_vars=[], selected_reg=None):
+        self._check_type(v)
+        if isinstance(v, Const):
+            if isinstance(v, ConstPtr):
+                tp = REF
+            elif isinstance(v, ConstFloat):
+                tp = FLOAT
+            else:
+                tp = INT
+            loc = self.get_scratch_reg(tp,
+                    self.temp_boxes + forbidden_vars,
+                    selected_reg=selected_reg)
+            immvalue = self.convert_to_imm(v)
+            self.assembler.load(loc, immvalue)
+            return loc
+        else:
+            return RegisterManager.return_constant(self, v,
+                                    forbidden_vars, selected_reg)
 
-class VFPRegisterManager(RegisterManager):
+
+class VFPRegisterManager(ARMRegisterManager):
     all_regs = r.all_vfp_regs
     box_types = [FLOAT]
     save_around_call_regs = r.all_vfp_regs
         reg = self.force_allocate_reg(v, selected_reg=r.d0)
         return reg
 
-    def ensure_value_is_boxed(self, thing, forbidden_vars=[]):
-        loc = None
-        if isinstance(thing, Const):
-            assert isinstance(thing, ConstFloat)
-            loc = self.get_scratch_reg(FLOAT, self.temp_boxes + forbidden_vars)
-            immvalue = self.convert_to_imm(thing)
-            self.assembler.load(loc, immvalue)
-        else:
-            loc = self.make_sure_var_in_reg(thing,
-                            forbidden_vars=self.temp_boxes + forbidden_vars)
-        return loc
-
-    def get_scratch_reg(self, type=FLOAT, forbidden_vars=[],
-                                                        selected_reg=None):
+    def get_scratch_reg(self, type=FLOAT, forbidden_vars=[], selected_reg=None):
         assert type == FLOAT  # for now
         box = TempFloat()
         self.temp_boxes.append(box)
         return reg
 
 
-class ARMv7RegisterManager(RegisterManager):
+class CoreRegisterManager(ARMRegisterManager):
     all_regs = r.all_regs
     box_types = None       # or a list of acceptable types
     no_lower_byte_regs = all_regs
             return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
         assert 0
 
-    def ensure_value_is_boxed(self, thing, forbidden_vars=None):
-        loc = None
-        if isinstance(thing, Const):
-            if isinstance(thing, ConstPtr):
-                tp = REF
-            else:
-                tp = INT
-            loc = self.get_scratch_reg(tp, forbidden_vars=self.temp_boxes
-                                                            + forbidden_vars)
-            immvalue = self.convert_to_imm(thing)
-            self.assembler.load(loc, immvalue)
-        else:
-            loc = self.make_sure_var_in_reg(thing,
-                            forbidden_vars=self.temp_boxes + forbidden_vars)
-        return loc
-
     def get_scratch_reg(self, type=INT, forbidden_vars=[], selected_reg=None):
         assert type == INT or type == REF
         box = TempBox()
 
     def make_sure_var_in_reg(self, var, forbidden_vars=[],
                          selected_reg=None, need_lower_byte=False):
-        assert 0, 'should not be called directly'
+        if var.type == FLOAT:
+            return self.vfprm.make_sure_var_in_reg(var, forbidden_vars,
+                                        selected_reg, need_lower_byte)
+        else:
+            return self.rm.make_sure_var_in_reg(var, forbidden_vars,
+                                        selected_reg, need_lower_byte)
 
     def convert_to_imm(self, value):
         if isinstance(value, ConstInt):
         fm = self.frame_manager
         asm = self.assembler
         self.vfprm = VFPRegisterManager(longevity, fm, asm)
-        self.rm = ARMv7RegisterManager(longevity, fm, asm)
+        self.rm = CoreRegisterManager(longevity, fm, asm)
 
     def prepare_loop(self, inputargs, operations):
         self._prepare(inputargs, operations)
         self.rm.before_call(force_store, save_all_regs)
         self.vfprm.before_call(force_store, save_all_regs)
 
-    def _ensure_value_is_boxed(self, thing, forbidden_vars=[]):
-        if thing.type == FLOAT:
-            return self.vfprm.ensure_value_is_boxed(thing, forbidden_vars)
-        else:
-            return self.rm.ensure_value_is_boxed(thing, forbidden_vars)
-
     def _sync_var(self, v):
         if v.type == FLOAT:
             self.vfprm._sync_var(v)
         imm_a0 = check_imm_box(a0)
         imm_a1 = check_imm_box(a1)
         if not imm_a0 and imm_a1:
-            l0 = self._ensure_value_is_boxed(a0, boxes)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
             l1 = self.convert_to_imm(a1)
         elif imm_a0 and not imm_a1:
             l0 = self.convert_to_imm(a0)
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         else:
-            l0 = self._ensure_value_is_boxed(a0, boxes)
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         return [l0, l1]
 
     def prepare_op_int_add(self, op, fcond):
         imm_a0 = check_imm_box(a0)
         imm_a1 = check_imm_box(a1)
         if not imm_a0 and imm_a1:
-            l0 = self._ensure_value_is_boxed(a0, boxes)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
             l1 = self.convert_to_imm(a1)
         elif imm_a0 and not imm_a1:
             l0 = self.convert_to_imm(a0)
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         else:
-            l0 = self._ensure_value_is_boxed(a0, boxes)
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         return [l0, l1]
 
     def prepare_op_int_sub(self, op, fcond):
         boxes = op.getarglist()
         a0, a1 = boxes
 
-        reg1 = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
-        reg2 = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
+        reg1 = self.make_sure_var_in_reg(a0, forbidden_vars=boxes)
+        reg2 = self.make_sure_var_in_reg(a1, forbidden_vars=boxes)
 
         self.possibly_free_vars(boxes)
         self.possibly_free_vars_for_op(op)
         return [reg1, reg2, res]
     
     def prepare_op_int_force_ge_zero(self, op, fcond):
-        argloc = self._ensure_value_is_boxed(op.getarg(0))
+        argloc = self.make_sure_var_in_reg(op.getarg(0))
         resloc = self.force_allocate_reg(op.result, [op.getarg(0)])
         return [argloc, resloc]
 
     def prepare_guard_int_mul_ovf(self, op, guard, fcond):
         boxes = op.getarglist()
-        reg1 = self._ensure_value_is_boxed(boxes[0], forbidden_vars=boxes)
-        reg2 = self._ensure_value_is_boxed(boxes[1], forbidden_vars=boxes)
+        reg1 = self.make_sure_var_in_reg(boxes[0], forbidden_vars=boxes)
+        reg2 = self.make_sure_var_in_reg(boxes[1], forbidden_vars=boxes)
         res = self.force_allocate_reg(op.result)
         return self._prepare_guard(guard, [reg1, reg2, res])
 
     prepare_guard_int_is_zero = prepare_op_unary_cmp('int_is_zero')
 
     def prepare_op_int_neg(self, op, fcond):
-        l0 = self._ensure_value_is_boxed(op.getarg(0))
+        l0 = self.make_sure_var_in_reg(op.getarg(0))
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         resloc = self.force_allocate_reg(op.result)
 
     def _prepare_llong_binop_xx(self, op, fcond):
         # arg 0 is the address of the function
-        loc0 = self._ensure_value_is_boxed(op.getarg(1))
-        loc1 = self._ensure_value_is_boxed(op.getarg(2))
+        loc0 = self.make_sure_var_in_reg(op.getarg(1))
+        loc1 = self.make_sure_var_in_reg(op.getarg(2))
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         res = self.vfprm.force_allocate_reg(op.result)
         return [loc0, loc1, res]
 
     def _prepare_llong_to_int(self, op, fcond):
-        loc0 = self._ensure_value_is_boxed(op.getarg(1))
+        loc0 = self.make_sure_var_in_reg(op.getarg(1))
         res = self.force_allocate_reg(op.result)
         return [loc0, res]
 
         return args
 
     def prepare_op_guard_true(self, op, fcond):
-        l0 = self._ensure_value_is_boxed(op.getarg(0))
+        l0 = self.make_sure_var_in_reg(op.getarg(0))
         args = self._prepare_guard(op, [l0])
         return args
 
         boxes = op.getarglist()
         a0, a1 = boxes
         imm_a1 = check_imm_box(a1)
-        l0 = self._ensure_value_is_boxed(a0, boxes)
+        l0 = self.make_sure_var_in_reg(a0, boxes)
         if not imm_a1:
-            l1 = self._ensure_value_is_boxed(a1, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         else:
             l1 = self.convert_to_imm(a1)
         assert op.result is None
     def prepare_op_guard_exception(self, op, fcond):
         boxes = op.getarglist()
         arg0 = ConstInt(rffi.cast(lltype.Signed, op.getarg(0).getint()))
-        loc = self._ensure_value_is_boxed(arg0)
+        loc = self.make_sure_var_in_reg(arg0)
         loc1 = self.get_scratch_reg(INT, boxes)
         if op.result in self.longevity:
             resloc = self.force_allocate_reg(op.result, boxes)
         return arglocs
 
     def prepare_op_guard_no_exception(self, op, fcond):
-        loc = self._ensure_value_is_boxed(
+        loc = self.make_sure_var_in_reg(
                     ConstInt(self.cpu.pos_exception()))
         arglocs = self._prepare_guard(op, [loc])
         return arglocs
         assert isinstance(op.getarg(0), Box)
         boxes = op.getarglist()
 
-        x = self._ensure_value_is_boxed(boxes[0], boxes)
+        x = self.make_sure_var_in_reg(boxes[0], boxes)
         y_val = rffi.cast(lltype.Signed, op.getarg(1).getint())
 
         arglocs = [x, None, None]
         boxes = op.getarglist()
         a0, a1 = boxes
         ofs, size, sign = unpack_fielddescr(op.getdescr())
-        base_loc = self._ensure_value_is_boxed(a0, boxes)
-        value_loc = self._ensure_value_is_boxed(a1, boxes)
+        base_loc = self.make_sure_var_in_reg(a0, boxes)
+        value_loc = self.make_sure_var_in_reg(a1, boxes)
         if check_imm_arg(ofs):
             ofs_loc = imm(ofs)
         else:
     def prepare_op_getfield_gc(self, op, fcond):
         a0 = op.getarg(0)
         ofs, size, sign = unpack_fielddescr(op.getdescr())
-        base_loc = self._ensure_value_is_boxed(a0)
+        base_loc = self.make_sure_var_in_reg(a0)
         immofs = imm(ofs)
         if check_imm_arg(ofs):
             ofs_loc = immofs
         t = unpack_interiorfielddescr(op.getdescr())
         ofs, itemsize, fieldsize, sign = t
         args = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
-        index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
+        base_loc = self.make_sure_var_in_reg(op.getarg(0), args)
+        index_loc = self.make_sure_var_in_reg(op.getarg(1), args)
         immofs = imm(ofs)
         if check_imm_arg(ofs):
             ofs_loc = immofs
         t = unpack_interiorfielddescr(op.getdescr())
         ofs, itemsize, fieldsize, sign = t
         args = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
-        index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
-        value_loc = self._ensure_value_is_boxed(op.getarg(2), args)
+        base_loc = self.make_sure_var_in_reg(op.getarg(0), args)
+        index_loc = self.make_sure_var_in_reg(op.getarg(1), args)
+        value_loc = self.make_sure_var_in_reg(op.getarg(2), args)
         immofs = imm(ofs)
         if check_imm_arg(ofs):
             ofs_loc = immofs
         assert isinstance(arraydescr, ArrayDescr)
         ofs = arraydescr.lendescr.offset
         arg = op.getarg(0)
-        base_loc = self._ensure_value_is_boxed(arg)
+        base_loc = self.make_sure_var_in_reg(arg)
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
         size, ofs, _ = unpack_arraydescr(op.getdescr())
         scale = get_scale(size)
         args = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(args[0], args)
-        ofs_loc = self._ensure_value_is_boxed(args[1], args)
-        value_loc = self._ensure_value_is_boxed(args[2], args)
+        base_loc = self.make_sure_var_in_reg(args[0], args)
+        ofs_loc = self.make_sure_var_in_reg(args[1], args)
+        value_loc = self.make_sure_var_in_reg(args[2], args)
         assert check_imm_arg(ofs)
         return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
     prepare_op_setarrayitem_raw = prepare_op_setarrayitem_gc
         boxes = op.getarglist()
         size, ofs, _ = unpack_arraydescr(op.getdescr())
         scale = get_scale(size)
-        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
-        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+        base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
+        ofs_loc = self.make_sure_var_in_reg(boxes[1], boxes)
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
 
     def prepare_op_strlen(self, op, fcond):
         args = op.getarglist()
-        l0 = self._ensure_value_is_boxed(op.getarg(0))
+        l0 = self.make_sure_var_in_reg(op.getarg(0))
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                          self.cpu.translate_support_code)
         immofs = imm(ofs_length)
 
     def prepare_op_strgetitem(self, op, fcond):
         boxes = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(boxes[0])
+        base_loc = self.make_sure_var_in_reg(boxes[0])
 
         a1 = boxes[1]
         imm_a1 = check_imm_box(a1)
         if imm_a1:
             ofs_loc = self.convert_to_imm(a1)
         else:
-            ofs_loc = self._ensure_value_is_boxed(a1, boxes)
+            ofs_loc = self.make_sure_var_in_reg(a1, boxes)
 
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
 
     def prepare_op_strsetitem(self, op, fcond):
         boxes = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
-        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
-        value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
+        base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
+        ofs_loc = self.make_sure_var_in_reg(boxes[1], boxes)
+        value_loc = self.make_sure_var_in_reg(boxes[2], boxes)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                          self.cpu.translate_support_code)
         assert itemsize == 1
     prepare_op_copyunicodecontent = void
 
     def prepare_op_unicodelen(self, op, fcond):
-        l0 = self._ensure_value_is_boxed(op.getarg(0))
+        l0 = self.make_sure_var_in_reg(op.getarg(0))
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                          self.cpu.translate_support_code)
         immofs = imm(ofs_length)
 
     def prepare_op_unicodegetitem(self, op, fcond):
         boxes = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
-        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+        base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
+        ofs_loc = self.make_sure_var_in_reg(boxes[1], boxes)
 
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
 
     def prepare_op_unicodesetitem(self, op, fcond):
         boxes = op.getarglist()
-        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
-        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
-        value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
+        base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
+        ofs_loc = self.make_sure_var_in_reg(boxes[1], boxes)
+        value_loc = self.make_sure_var_in_reg(boxes[2], boxes)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                          self.cpu.translate_support_code)
         scale = itemsize / 2
         if imm_arg:
             argloc = self.convert_to_imm(arg)
         else:
-            argloc = self._ensure_value_is_boxed(arg)
+            argloc = self.make_sure_var_in_reg(arg)
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         resloc = self.force_allocate_reg(op.result)
         # twice from the memory.
         N = op.numargs()
         args = op.getarglist()
-        arglocs = [self._ensure_value_is_boxed(op.getarg(i), args)
+        arglocs = [self.make_sure_var_in_reg(op.getarg(i), args)
                                                               for i in range(N)]
         tmp = self.get_scratch_reg(INT, args)
         assert tmp not in arglocs
                             float_result=False, name='prepare_guard_float_ge')
 
     def prepare_op_math_sqrt(self, op, fcond):
-        loc = self._ensure_value_is_boxed(op.getarg(1))
+        loc = self.make_sure_var_in_reg(op.getarg(1))
         self.possibly_free_vars_for_op(op)
         self.free_temp_vars()
         res = self.vfprm.force_allocate_reg(op.result)
         return [loc, res]
 
     def prepare_op_cast_float_to_int(self, op, fcond):
-        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        loc1 = self.make_sure_var_in_reg(op.getarg(0))
         res = self.rm.force_allocate_reg(op.result)
         return [loc1, res]
 
     def prepare_op_cast_int_to_float(self, op, fcond):
-        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        loc1 = self.make_sure_var_in_reg(op.getarg(0))
         res = self.vfprm.force_allocate_reg(op.result)
         return [loc1, res]
 
         return [loc, res]
 
     def prepare_op_cast_float_to_singlefloat(self, op, fcond):
-        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        loc1 = self.make_sure_var_in_reg(op.getarg(0))
         res = self.force_allocate_reg(op.result)
         return [loc1, res]
-    
+
     def prepare_op_cast_singlefloat_to_float(self, op, fcond):
-        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        loc1 = self.make_sure_var_in_reg(op.getarg(0))
         res = self.force_allocate_reg(op.result)
         return [loc1, res]
 

pypy/jit/backend/llsupport/regalloc.py

         """
         raise NotImplementedError("Abstract")
 
-    def get_scratch_reg(self, forbidden_vars=[]):
+    def get_scratch_reg(self, type, forbidden_vars=[], selected_reg=None):
         """ Platform specific - Allocates a temporary register """
         raise NotImplementedError("Abstract")
 

pypy/jit/metainterp/test/test_string.py

             return result
         res = self.meta_interp(main, [9])
         assert res == main(9)
+
+    def test_bytearray(self):
+        py.test.skip("implement it")
+        def f(i):
+            b = bytearray("abc")
+            b[1] = i
+            return b[1]
+
+        res = self.interp_operations(f, [13])
+        assert res == 13

pypy/module/_cffi_backend/ctypeenum.py

         except OperationError, e:
             if not e.match(space, space.w_TypeError):
                 raise
-        if space.isinstance_w(w_ob, space.w_str):
+        if space.isinstance_w(w_ob, space.w_basestring):
             value = self.convert_enum_string_to_int(space.str_w(w_ob))
             value = r_ulonglong(value)
             misc.write_raw_integer_data(cdata, value, self.size)
         space = self.space
         return self.convert_enum_string_to_int(space.str_w(w_ob))
 
+    def cast_unicode(self, w_ob):
+        return self.cast_str(w_ob)
+
     def convert_enum_string_to_int(self, s):
         space = self.space
         if s.startswith('#'):
             try:
-                return int(s[1:])     # xxx is it RPython?
+                return int(s[1:])
             except ValueError:
                 raise OperationError(space.w_ValueError,
                                      space.wrap("invalid literal after '#'"))

pypy/module/_cffi_backend/test/_backend_test_c.py

     assert p.a1 == "c"
     e = py.test.raises(TypeError, newp, BStructPtr, [None])
     assert "must be a str or int, not NoneType" in str(e.value)
+    if sys.version_info < (3,):
+        p.a1 = unicode("def")
+        assert p.a1 == "def" and type(p.a1) is str
+        py.test.raises(UnicodeEncodeError, "p.a1 = unichr(1234)")
+        BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,))
+        assert string(cast(BEnum2, unicode('abc'))) == 'abc'
 
 def test_enum_overflow():
     for ovf in (2**63, -2**63-1, 2**31, -2**31-1):

pypy/module/micronumpy/__init__.py

 from pypy.interpreter.mixedmodule import MixedModule
+from pypy.module.micronumpy.interp_boxes import long_double_size
 
 
 class Module(MixedModule):
         'float16': 'interp_boxes.W_Float16Box',
         'float32': 'interp_boxes.W_Float32Box',
         'float64': 'interp_boxes.W_Float64Box',
+        'longdouble': 'interp_boxes.W_LongDoubleBox',
+        'longfloat': 'interp_boxes.W_LongDoubleBox',
         'intp': 'types.IntP.BoxType',
         'uintp': 'types.UIntP.BoxType',
         'flexible': 'interp_boxes.W_FlexibleBox',
         'complex_': 'interp_boxes.W_Complex128Box',
         'complex128': 'interp_boxes.W_Complex128Box',
         'complex64': 'interp_boxes.W_Complex64Box',
+        'clongdouble': 'interp_boxes.W_CLongDoubleBox',
+        'clongfloat': 'interp_boxes.W_CLongDoubleBox',
     }
 
     # ufuncs
         'max': 'app_numpy.max',
         'arange': 'app_numpy.arange',
     }
+
+if long_double_size == 16:
+    Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box'
+    Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box'
+elif long_double_size == 12:
+    Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box'
+    Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box'

pypy/module/micronumpy/interp_boxes.py

 from pypy.objspace.std.inttype import int_typedef
 from pypy.objspace.std.complextype import complex_typedef
 from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rpython.lltypesystem import rffi
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage
 
 MIXIN_32 = (int_typedef,) if LONG_BIT == 32 else ()
 MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else ()
 
+# Is this the proper place for this?
+long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True)
+import os
+if long_double_size == 8 and os.name == 'nt':
+    # this is a lie, or maybe a wish
+    long_double_size = 12
+
 
 def new_dtype_getter(name):
     def _get_dtype(space):
 class W_Float64Box(W_FloatingBox, PrimitiveBox):
     descr__new__, _get_dtype = new_dtype_getter("float64")
 
-
 class W_FlexibleBox(W_GenericBox):
     def __init__(self, arr, ofs, dtype):
         self.arr = arr # we have to keep array alive
     descr__new__, _get_dtype = new_dtype_getter("complex128")
     _COMPONENTS_BOX = W_Float64Box
 
+if long_double_size == 12:
+    class W_Float96Box(W_FloatingBox, PrimitiveBox):
+        descr__new__, _get_dtype = new_dtype_getter("float96")
+
+    W_LongDoubleBox = W_Float96Box
+
+    class W_Complex192Box(ComplexBox, W_ComplexFloatingBox):
+        descr__new__, _get_dtype = new_dtype_getter("complex192")
+        _COMPONENTS_BOX = W_Float96Box
+
+    W_CLongDoubleBox = W_Complex192Box
+
+elif long_double_size == 16:
+    class W_Float128Box(W_FloatingBox, PrimitiveBox):
+        descr__new__, _get_dtype = new_dtype_getter("float128")
+    W_LongDoubleBox = W_Float128Box
+
+    class W_Complex256Box(ComplexBox, W_ComplexFloatingBox):
+        descr__new__, _get_dtype = new_dtype_getter("complex256")
+        _COMPONENTS_BOX = W_Float128Box
+
+    W_CLongDoubleBox = W_Complex256Box
+
+else:
+    W_LongDoubleBox = W_Float64Box
+    W_CLongDoubleBox = W_Complex64Box
+
     
 W_GenericBox.typedef = TypeDef("generic",
     __module__ = "numpypy",
     __new__ = interp2app(W_Float64Box.descr__new__.im_func),
 )
 
+if long_double_size == 12:
+    W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef),
+        __module__ = "numpypy",
+
+        __new__ = interp2app(W_Float96Box.descr__new__.im_func),
+    )
+
+    W_Complex192Box.typedef = TypeDef("complex192", (W_ComplexFloatingBox.typedef, complex_typedef),
+        __module__ = "numpypy",
+        __new__ = interp2app(W_Complex192Box.descr__new__.im_func),
+        real = GetSetProperty(W_ComplexFloatingBox.descr_get_real),
+        imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag),
+    )
+
+elif long_double_size == 16:
+    W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef),
+        __module__ = "numpypy",
+
+        __new__ = interp2app(W_Float128Box.descr__new__.im_func),
+    )
+
+    W_Complex256Box.typedef = TypeDef("complex256", (W_ComplexFloatingBox.typedef, complex_typedef),
+        __module__ = "numpypy",
+        __new__ = interp2app(W_Complex256Box.descr__new__.im_func),
+        real = GetSetProperty(W_ComplexFloatingBox.descr_get_real),
+        imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag),
+    )
 
 W_FlexibleBox.typedef = TypeDef("flexible", W_GenericBox.typedef,
     __module__ = "numpypy",

pypy/module/micronumpy/interp_dtype.py

 SIGNEDLTR = "i"
 BOOLLTR = "b"
 FLOATINGLTR = "f"
+COMPLEXLTR = "c"
 VOIDLTR = 'V'
 STRINGLTR = 'S'
 UNICODELTR = 'U'
         return self.kind == SIGNEDLTR
 
     def is_complex_type(self):
-        return (self.num == 14 or self.num == 15)
+        return (self.num == 14 or self.num == 15 or self.num == 16)
 
     def is_bool_type(self):
         return self.kind == BOOLLTR
             alternate_constructors=[space.w_float],
             aliases=["float"],
         )
-        # self.w_float128dtype = W_Dtype(
-        #     types.Float128(),
-        #     num=13,
-        #     kind=FLOATINGLTR,
-        #     name="float128",
-        #     ...
-        # )
         self.w_complex64dtype = W_Dtype(
             types.Complex64(),
             num=14,
-            kind=FLOATINGLTR,
+            kind=COMPLEXLTR,
             name="complex64",
             char="F",
             w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
         self.w_complex128dtype = W_Dtype(
             types.Complex128(),
             num=15,
-            kind=FLOATINGLTR,
+            kind=COMPLEXLTR,
             name="complex128",
             char="D",
             w_box_type = space.gettypefor(interp_boxes.W_Complex128Box),
             alternate_constructors=[space.w_complex],
             aliases=["complex"],
         )
+        if interp_boxes.long_double_size == 12:
+            self.w_float96dtype = W_Dtype(
+                types.Float96(),
+                num=13,
+                kind=FLOATINGLTR,
+                name="float96",
+                char="g",
+                w_box_type=space.gettypefor(interp_boxes.W_Float96Box),
+                aliases=["longfloat", "longdouble"],
+            )
+            self.w_longdouble = self.w_float96dtype
+
+            self.w_complex192dtype = W_Dtype(
+                types.Complex192(),
+                num=16,
+                kind=COMPLEXLTR,
+                name="complex192",
+                char="G",
+                w_box_type = space.gettypefor(interp_boxes.W_Complex192Box),
+                alternate_constructors=[space.w_complex],
+                aliases=["clongdouble", "clongfloat"],
+            )
+            self.w_clongdouble = self.w_complex192dtype
+
+        elif interp_boxes.long_double_size == 16:
+            self.w_float128dtype = W_Dtype(
+                types.Float128(),
+                num=13,
+                kind=FLOATINGLTR,
+                name="float128",
+                char="g",
+                w_box_type=space.gettypefor(interp_boxes.W_Float128Box),
+                aliases=["longfloat", "longdouble"],
+            )
+            self.w_longdouble = self.w_float128dtype
+
+            self.w_complex256dtype = W_Dtype(
+                types.Complex256(),
+                num=16,
+                kind=COMPLEXLTR,
+                name="complex256",
+                char="G",
+                w_box_type = space.gettypefor(interp_boxes.W_Complex256Box),
+                alternate_constructors=[space.w_complex],
+                aliases=["clongdouble", "clongfloat"],
+            )
+            self.w_clongdouble = self.w_complex256dtype
+        else:
+            self.w_float64dtype.aliases += ["longfloat", "longdouble"]
+            self.w_longdouble = self.w_float64dtype
+            self.w_clongdouble = self.w_complex64dtype
         self.w_stringdtype = W_Dtype(
             types.StringType(1),
             num=18,
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
             self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype,
             self.w_int64dtype, self.w_uint64dtype,
-            self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, self.w_complex64dtype,
-            self.w_complex128dtype,
+            self.w_float16dtype, self.w_float32dtype, self.w_float64dtype,
+            self.w_longdouble,
+            self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble,
             self.w_stringdtype, self.w_unicodedtype,
             self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype,
         ]
         self.float_dtypes_by_num_bytes = sorted(
             (dtype.itemtype.get_element_size(), dtype)
-            for dtype in [self.w_float16dtype, self.w_float32dtype, self.w_float64dtype]
+            for dtype in [self.w_float16dtype, self.w_float32dtype,
+                          self.w_float64dtype, self.w_longdouble]
         )
         self.dtypes_by_name = {}
         # we reverse, so the stuff with lower numbers override stuff with
             'LONGLONG': self.w_int64dtype,
             'SHORT': self.w_int16dtype,
             'VOID': self.w_voiddtype,
-            #'LONGDOUBLE':,
+            'LONGDOUBLE': self.w_longdouble,
             'UBYTE': self.w_uint8dtype,
             'UINTP': self.w_ulongdtype,
             'ULONG': self.w_ulongdtype,
             #'OBJECT',
             'ULONGLONG': self.w_uint64dtype,
             'STRING': self.w_stringdtype,
-            #'CDOUBLE',
+            'CDOUBLE': self.w_complex64dtype,
             #'DATETIME',
             'UINT': self.w_uint32dtype,
             'INTP': self.w_intpdtype,
             'USHORT': self.w_uint16dtype,
             'FLOAT': self.w_float32dtype,
             'BOOL': self.w_booldtype,
-            #, 'CLONGDOUBLE']
+            'CLONGDOUBLE': self.w_clongdouble,
         }
         typeinfo_partial = {
             'Generic': interp_boxes.W_GenericBox,
             'Integer': interp_boxes.W_IntegerBox,
             'SignedInteger': interp_boxes.W_SignedIntegerBox,
             'UnsignedInteger': interp_boxes.W_UnsignedIntegerBox,
-            #'ComplexFloating',
+            'ComplexFloating': interp_boxes.W_ComplexFloatingBox,
             'Number': interp_boxes.W_NumberBox,
             'Floating': interp_boxes.W_FloatingBox
         }

pypy/module/micronumpy/interp_ufuncs.py

     if promote_bools and (dt1.kind == dt2.kind == interp_dtype.BOOLLTR):
         return interp_dtype.get_dtype_cache(space).w_int8dtype
 
-    # Everything promotes to complex
-    if dt2.num == 14 or dt2.num == 15 or dt1.num == 14 or dt2.num == 15:
-        if dt2.num == 15 or dt1.num == 15:
+    # Everything numeric promotes to complex
+    if dt2.is_complex_type() or dt1.is_complex_type():
+        if dt2.num == 14:
+            return interp_dtype.get_dtype_cache(space).w_complex64dtype
+        elif dt2.num == 15:
             return interp_dtype.get_dtype_cache(space).w_complex128dtype
+        elif dt2.num == 16:
+            return interp_dtype.get_dtype_cache(space).w_clongdouble
         else:
-            return interp_dtype.get_dtype_cache(space).w_complex64dtype
+            raise OperationError(space.w_TypeError, space.wrap("Unsupported types"))
+
     
     if promote_to_float:
         return find_unaryop_result_dtype(space, dt2, promote_to_float=True)
     if not allow_complex and (dt.is_complex_type()):
         raise OperationError(space.w_TypeError, space.wrap("Unsupported types"))
     if promote_to_float:
-        if dt.kind == interp_dtype.FLOATINGLTR:
+        if dt.kind == interp_dtype.FLOATINGLTR or dt.kind==interp_dtype.COMPLEXLTR:
             return dt
         if dt.num >= 5:
             return interp_dtype.get_dtype_cache(space).w_float64dtype

pypy/module/micronumpy/test/test_complex.py

 
     def test_fmax(self):
         from _numpypy import fmax, array
-        import math
         nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf')
         a = array((complex(ninf, 10), complex(10, ninf), 
                    complex( inf, 10), complex(10,  inf),
 
     def test_fmin(self):
         from _numpypy import fmin, array
-        import math
         nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf')
         a = array((complex(ninf, 10), complex(10, ninf), 
                    complex( inf, 10), complex(10,  inf),
         raises(TypeError, signbit, complex(1,1))
 
     def test_reciprocal(self):
-        from _numpypy import array, reciprocal, complex64, complex128
+        from _numpypy import array, reciprocal, complex64, complex128, clongdouble
 
         inf = float('inf')
         nan = float('nan')
                     complex(-r, i), 
                     -0j, 0j, cnan, 
                     cnan, cnan, cnan]
-        for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), ):
+        for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), (clongdouble, 2e-15)):
             actual = reciprocal(array([orig], dtype=c))
             for b, a, e in zip(orig, actual, expected):
                 assert (a[0].real - e.real) < rel_err
         raises(TypeError, copysign, a, b)
 
     def test_exp2(self):
-        import math 
-        from _numpypy import array, exp2, complex128, complex64
+        from _numpypy import array, exp2, complex128, complex64, clongfloat
         inf = float('inf')
         ninf = -float('inf')
         nan = float('nan')
         cmpl = complex
-        for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7)):
+        for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7), (clongfloat, 2e-15)):
             a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.),
                        cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.),
                        cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.),
     def test_basic(self):
         from _numpypy import (complex128, complex64, add, array, dtype,
             subtract as sub, multiply, divide, negative, abs, floor_divide,
-            real, imag, sign)
+            real, imag, sign, clongfloat)
         from _numpypy import (equal, not_equal, greater, greater_equal, less,
                 less_equal, isnan)
         assert real(4.0) == 4.0
         a = array([complex(3.0, 4.0)])
         b = a.real
         assert b.dtype == dtype(float)
-        for complex_ in complex64, complex128:
+        for complex_ in complex64, complex128, clongfloat:
 
             O = complex(0, 0)
             c0 = complex_(complex(2.5, 0))

pypy/module/micronumpy/test/test_dtypes.py

     def test_bool_binop_types(self):
         from _numpypy import array, dtype
         types = [
-            '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e',
+            '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 
+            'e'
         ]
+        if array([0], dtype='longdouble').itemsize > 8:
+            types += ['g', 'G']
         a = array([True], '?')
         for t in types:
             assert (a + array([0], t)).dtype is dtype(t)
             (numpy.float16, 10.),
             (numpy.float32, 2.0),
             (numpy.float64, 4.32),
+            (numpy.longdouble, 4.32),
         ]:
             assert hash(tp(value)) == hash(value)
 
         assert numpy.float64('23.4') == numpy.float64(23.4)
         raises(ValueError, numpy.float64, '23.2df')
 
+    def test_longfloat(self):
+        import _numpypy as numpy
+        # it can be float96 or float128
+        if numpy.longfloat != numpy.float64:
+            assert numpy.longfloat.mro()[1:] == [numpy.floating,
+                                       numpy.inexact, numpy.number, 
+                                       numpy.generic, object]
+        a = numpy.array([1, 2, 3], numpy.longdouble)
+        assert repr(type(a[1])) == repr(numpy.longdouble)
+        assert numpy.float64(12) == numpy.longdouble(12)
+        assert numpy.float64(12) == numpy.longfloat(12)
+        raises(ValueError, numpy.longfloat, '23.2df')
+
     def test_complex_floating(self):
         import _numpypy as numpy
 
 
         assert numpy.dtype(complex).type is numpy.complex128
         assert numpy.dtype("complex").type is numpy.complex128
+        d = numpy.dtype('complex64')
+        assert d.kind == 'c'
+        assert d.num == 14
+        assert d.char == 'F'
+        
+
 
     def test_subclass_type(self):
         import _numpypy as numpy

pypy/module/micronumpy/test/test_numarray.py

 
     def test_fromstring_types(self):
         from _numpypy import (fromstring, int8, int16, int32, int64, uint8,
-            uint16, uint32, float16, float32, float64)
+            uint16, uint32, float16, float32, float64, longfloat, array)
         a = fromstring('\xFF', dtype=int8)
         assert a[0] == -1
         b = fromstring('\xFF', dtype=uint8)
         assert j[0] == 12
         k = fromstring(self.float16val, dtype=float16)
         assert k[0] == float16(5.)
+        dt =  array([5],dtype=longfloat).dtype
+        if dt.itemsize == 12:
+            from _numpypy import float96
+            m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96)
+        elif dt.itemsize==16:
+            from _numpypy import float128
+            m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128)
+        elif dt.itemsize == 8:
+            skip('longfloat is float64')
+        else:
+            skip('unknown itemsize for longfloat')
+        assert m[0] == longfloat(5.)
 
     def test_fromstring_invalid(self):
-        from _numpypy import fromstring, uint16, uint8, int32
+        from _numpypy import fromstring, uint16, uint8
         #default dtype is 64-bit float, so 3 bytes should fail
         raises(ValueError, fromstring, "\x01\x02\x03")
         #3 bytes is not modulo 2 bytes (int16)

pypy/module/micronumpy/types.py

 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rstruct.runpack import runpack
 from pypy.rlib.rstruct.nativefmttable import native_is_bigendian
-from pypy.rlib.rstruct.ieee import float_pack, float_unpack, unpack_float
+from pypy.rlib.rstruct.ieee import (float_pack, float_unpack, 
+                                    unpack_float, unpack_float128)
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib import jit
 from pypy.rlib.rstring import StringBuilder
     ComponentBoxType = interp_boxes.W_Float32Box
 
 
-
 NonNativeComplex64 = Complex64
 
 class Complex128(ComplexFloating, BaseType):
 
 NonNativeComplex128 = Complex128
 
+if interp_boxes.long_double_size == 12:
+    class Float96(BaseType, Float):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float96Box
+        format_code = "q"
+
+        def runpack_str(self, s):
+            assert len(s) == 12
+            fval = unpack_float128(s, native_is_bigendian)
+            return self.box(fval)
+
+    class NonNativeFloat96(Float96):
+        pass
+
+    class Complex192(ComplexFloating, BaseType):
+        _attrs_ = ()
+
+        T = rffi.CHAR
+        _COMPONENTS_T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Complex192Box
+        ComponentBoxType = interp_boxes.W_Float96Box
+
+    NonNativeComplex192 = Complex192
+
+
+elif interp_boxes.long_double_size == 16:
+    class Float128(BaseType, Float):
+        _attrs_ = ()
+
+        T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Float128Box
+        format_code = "q"
+
+        def runpack_str(self, s):
+            assert len(s) == 16
+            fval = unpack_float128(s, native_is_bigendian)
+            return self.box(fval)
+
+    class NonNativeFloat128(Float128):
+        pass
+
+    class Complex256(ComplexFloating, BaseType):
+        _attrs_ = ()
+
+        T = rffi.CHAR
+        _COMPONENTS_T = rffi.LONGDOUBLE
+        BoxType = interp_boxes.W_Complex256Box
+        ComponentBoxType = interp_boxes.W_Float128Box
+
+
+    NonNativeComplex256 = Complex256
+
 class BaseStringType(object):
     _mixin_ = True
 

pypy/rlib/parsing/ebnfparse.py

                     real_expansions.append(expansion)
                     real_changes.append(change)
                     continue
-                assert n != len(expansion), (
-                    "currently an expansion needs at least one"
-                    "symbol that always has to occur")
+                if n == len(expansion):
+                    raise ValueError("Rule %r's expansion needs "
+                        "at least one symbol with >0 repetitions"
+                        % rule.nonterminal)
                 slices = []
                 start = 0
                 for i, (maybe, symbol) in enumerate(

pypy/rlib/parsing/test/test_ebnfparse.py

 """)
     excinfo = py.test.raises(ValueError, make_parse_function, regexs, rules)
     assert "primari" in str(excinfo.value)
- 
+
 def test_starred_star():
     regexs, rules, ToAST = parse_ebnf("""
 IGNORE: " ";
     t = ToAST().transform(t)
     assert len(t.children) == 6
     excinfo = py.test.raises(ParseError, parse, "a")
+
+def test_zero_repetition_production():
+    grammar = """
+IGNORE: " ";
+foo: "A"?;
+"""
+    excinfo = py.test.raises(ValueError, parse_ebnf, grammar)
+    assert "foo" in str(excinfo.value)

pypy/rlib/rarithmetic.py

File contents unchanged.

pypy/rlib/rmmap.py

 PTR = rffi.CCHARP
 
 if _CYGWIN:
-    c_malloc, _ = external('malloc', [size_t], PTR)
-    c_free, _ = external('free', [PTR], lltype.Void)
+    # XXX: macro=True hack for newer versions of Cygwin (as of 12/2012)
+    c_malloc, _ = external('malloc', [size_t], PTR, macro=True)
+    c_free, _ = external('free', [PTR], lltype.Void, macro=True)
 
 c_memmove, _ = external('memmove', [PTR, PTR, size_t], lltype.Void)
 

pypy/rlib/rstruct/ieee.py

         int_part += 1
     return int_part
 
+def float_unpack80(QQ):
+    '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format
+    into a long double float
+    '''
+    MIN_EXP = -16381
+    MAX_EXP = 16384 
+    MANT_DIG = 64   
+    TOPBITS = 80 - 64
+    one = r_ulonglong(1)
+    if len(QQ) != 2:
+        raise ValueError("QQ must be two 64 bit uints")
+    if not objectmodel.we_are_translated():
+        # This tests generates wrong code when translated:
+        # with gcc, shifting a 64bit int by 64 bits does
+        # not change the value.
+        if QQ[1] >> TOPBITS:
+            raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS))
+
+    # extract pieces with explicit one in MANT_DIG
+    sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1)
+    exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1)))
+    mant = QQ[0]
+
+    if exp == MAX_EXP - MIN_EXP + 2:
+        # nan or infinity
+        result = rfloat.NAN if mant &((one << MANT_DIG - 1) - 1) else rfloat.INFINITY
+    else:
+        # normal
+        result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1)
+    return -result if sign else result
+
 
 def float_unpack(Q, size):
-    """Convert a 16-bit, 32-bit or 64-bit integer created
+    """Convert a 16-bit, 32-bit 64-bit integer created
     by float_pack into a Python float."""
+    if size == 8:
+        MIN_EXP = -1021  # = sys.float_info.min_exp
+        MAX_EXP = 1024   # = sys.float_info.max_exp
+        MANT_DIG = 53    # = sys.float_info.mant_dig
+        BITS = 64
+        one = r_ulonglong(1)
+    elif size == 4:
+        MIN_EXP = -125   # C's FLT_MIN_EXP
+        MAX_EXP = 128    # FLT_MAX_EXP
+        MANT_DIG = 24    # FLT_MANT_DIG
+        BITS = 32
+        one = r_ulonglong(1)
+    elif size == 2:
+        MIN_EXP = -13   
+        MAX_EXP = 16    
+        MANT_DIG = 11
+        BITS = 16
+        one = r_ulonglong(1)
+    else:
+        raise ValueError("invalid size value")
 
+    if not objectmodel.we_are_translated():
+        # This tests generates wrong code when translated:
+        # with gcc, shifting a 64bit int by 64 bits does
+        # not change the value.
+        if Q >> BITS:
+            raise ValueError("input '%r' out of range '%r'" % (Q, Q>>BITS))
+
+    # extract pieces with assumed 1.mant values
+    sign = rarithmetic.intmask(Q >> BITS - 1)
+    exp = rarithmetic.intmask((Q & ((one << BITS - 1) - (one << MANT_DIG - 1))) >> MANT_DIG - 1)
+    mant = Q & ((one << MANT_DIG - 1) - 1)
+
+    if exp == MAX_EXP - MIN_EXP + 2:
+        # nan or infinity
+        result = rfloat.NAN if mant else rfloat.INFINITY
+    elif exp == 0:
+        # subnormal or zero
+        result = math.ldexp(mant, MIN_EXP - MANT_DIG)
+    else:
+        # normal: add implicit one value
+        mant += one << MANT_DIG - 1
+        result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1)
+    return -result if sign else result
+
+
+def float_pack(x, size):
+    """Convert a Python float x into a 64-bit unsigned integer
+    with the same byte representation."""
     if size == 8:
         MIN_EXP = -1021  # = sys.float_info.min_exp
         MAX_EXP = 1024   # = sys.float_info.max_exp
         MAX_EXP = 16    
         MANT_DIG = 11
         BITS = 16
-    else:
-        raise ValueError("invalid size value")
-
-    if not objectmodel.we_are_translated():
-        # This tests generates wrong code when translated:
-        # with gcc, shifting a 64bit int by 64 bits does
-        # not change the value.
-        if Q >> BITS:
-            raise ValueError("input out of range")
-
-    # extract pieces
-    one = r_ulonglong(1)
-    sign = rarithmetic.intmask(Q >> BITS - 1)
-    exp = rarithmetic.intmask((Q & ((one << BITS - 1) - (one << MANT_DIG - 1))) >> MANT_DIG - 1)
-    mant = Q & ((one << MANT_DIG - 1) - 1)
-
-    if exp == MAX_EXP - MIN_EXP + 2:
-        # nan or infinity
-        result = rfloat.NAN if mant else rfloat.INFINITY
-    elif exp == 0:
-        # subnormal or zero
-        result = math.ldexp(mant, MIN_EXP - MANT_DIG)
-    else:
-        # normal
-        mant += one << MANT_DIG - 1
-        result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1)
-    return -result if sign else result
-
-
-def float_pack(x, size):
-    """Convert a Python float x into a 64-bit unsigned integer
-    with the same byte representation."""
-
-    if size == 8:
-        MIN_EXP = -1021  # = sys.float_info.min_exp
-        MAX_EXP = 1024   # = sys.float_info.max_exp
-        MANT_DIG = 53    # = sys.float_info.mant_dig
-        BITS = 64
-    elif size == 4:
-        MIN_EXP = -125   # C's FLT_MIN_EXP
-        MAX_EXP = 128    # FLT_MAX_EXP
-        MANT_DIG = 24    # FLT_MANT_DIG
-        BITS = 32
-    elif size == 2:
-        MIN_EXP = -13   
-        MAX_EXP = 16    
-        MANT_DIG = 11
-        BITS = 16
+    elif size == 16 or size == 12:
+        #Implement a x86-hardware extended 80 bit format
+        # with explicit 1 in bit 64
+        MIN_EXP = -16381
+        MAX_EXP = 16384
+        MANT_DIG = 64 
+        BITS = 80
     else:
         raise ValueError("invalid size value")
 
         assert 0 <= mant < 1 << MANT_DIG - 1
         assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
         assert 0 <= sign <= 1
-
+    if size==12 or size == 16:
+        mant |= r_ulonglong(1) <<(MANT_DIG-1) #1 is explicit for 80bit extended format
+        exp = exp << 1
     exp = r_ulonglong(exp)
     sign = r_ulonglong(sign)
     return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant
 
+def float_pack80(x):
+    """Convert a Python float x into two 64-bit unsigned integers
+    with 80 bit extended representation."""
+    MIN_EXP = -16381
+    MAX_EXP = 16384
+    MANT_DIG = 64 
+    BITS = 80
+
+    sign = rfloat.copysign(1.0, x) < 0.0
+    if not rfloat.isfinite(x):
+        if rfloat.isinf(x):
+            mant = r_ulonglong(0)
+            exp = MAX_EXP - MIN_EXP + 2
+        else:  # rfloat.isnan(x):
+            mant = (r_ulonglong(1) << (MANT_DIG-2)) - 1 # other values possible
+            exp = MAX_EXP - MIN_EXP + 2
+    elif x == 0.0:
+        mant = r_ulonglong(0)
+        exp = 0
+    else:
+        m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
+        exp = e - (MIN_EXP - 1)
+        if exp > 0:
+            # Normal case. Avoid uint64 overflow by using MANT_DIG-1
+            mant = round_to_nearest(m * (r_ulonglong(1) << MANT_DIG - 1))
+        else:
+            # Subnormal case.
+            if exp + MANT_DIG - 1 >= 0:
+                mant = round_to_nearest(m * (r_ulonglong(1) << exp + MANT_DIG - 1))
+            else:
+                mant = r_ulonglong(0)
+            exp = 0
+
+        # Special case: rounding produced a MANT_DIG-bit mantissa.
+        if mant == r_ulonglong(1) << MANT_DIG - 1:
+            mant = r_ulonglong(0)
+            exp += 1
+
+        # Raise on overflow (in some circumstances, may want to return
+        # infinity instead).
+        if exp >= MAX_EXP - MIN_EXP + 2:
+             raise OverflowError("float too large to pack in this format")
+
+    # check constraints
+    if not objectmodel.we_are_translated():
+        assert 0 <= mant < 1 << MANT_DIG - 1
+        assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
+        assert 0 <= sign <= 1
+    mant = mant << 1
+    exp = r_ulonglong(exp)
+    sign = r_ulonglong(sign)
+    return (mant, (sign << BITS - MANT_DIG - 1) | exp)
+
 
 @jit.unroll_safe
 def pack_float(result, x, size, be):
     l = []
-    unsigned = float_pack(x, size)
-    for i in range(size):
-        l.append(chr((unsigned >> (i * 8)) & 0xFF))
+    if size == 12 or size == 16:
+        unsigned = float_pack80(x)
+        for i in range(8):
+            l.append(chr((unsigned[0] >> (i * 8)) & 0xFF))
+        for i in range(size - 8):
+            l.append(chr((unsigned[1] >> (i * 8)) & 0xFF))
+    else:
+        unsigned = float_pack(x, size)
+        for i in range(size):
+            l.append(chr((unsigned >> (i * 8)) & 0xFF))
     if be:
         l.reverse()
     result.append("".join(l))
 
-
 def unpack_float(s, be):
     unsigned = r_ulonglong(0)
     for i in range(len(s)):
         c = ord(s[len(s) - 1 - i if be else i])
         unsigned |= r_ulonglong(c) << (i * 8)
     return float_unpack(unsigned, len(s))
+
+def unpack_float128(s, be):
+    QQ = [r_ulonglong(0), r_ulonglong(0)]
+    for i in range(8):
+        c = ord(s[len(s) - 1 - i if be else i])
+        QQ[0] |= r_ulonglong(c) << (i * 8)
+    for i in range(8, len(s)):
+        c = ord(s[len(s) - 1 - i if be else i])
+        QQ[1] |= r_ulonglong(c) << ((i - 8) * 8)
+    return float_unpack80(QQ)

pypy/rlib/rstruct/test/test_ieee.py

 import struct
 
 from pypy.rlib.rfloat import isnan
-from pypy.rlib.rstruct.ieee import float_pack, float_unpack
+from pypy.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80
 
 
 class TestFloatPacking:
         y = float_unpack(Q, 8)
         assert repr(x) == repr(y)
 
+        Q = float_pack80(x)
+        y = float_unpack80(Q)
+        assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q)
+
         # check that packing agrees with the struct module
         struct_pack8 = struct.unpack('<Q', struct.pack('<d', x))[0]
         float_pack8 = float_pack(x, 8)
             float_pack4 = "overflow"
         assert struct_pack4 == float_pack4
 
+        if float_pack4 == "overflow":
+            return
+
         # if we didn't overflow, try round-tripping the binary32 value
-        if float_pack4 != "overflow":
-            roundtrip = float_pack(float_unpack(float_pack4, 4), 4)
-            assert float_pack4 == roundtrip
+        roundtrip = float_pack(float_unpack(float_pack4, 4), 4)
+        assert float_pack4 == roundtrip
+
+        try:
+            float_pack2 = float_pack(x, 2)
+        except OverflowError:
+            return
+
+        roundtrip = float_pack(float_unpack(float_pack2, 2), 2)