[pypy-svn] pypy default: Import float2longlong() from the jitypes2 branch, and use it in
arigo
commits-noreply at bitbucket.org
Fri Jan 14 15:06:17 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r40671:2e48ec813eda
Date: 2011-01-14 14:16 +0100
http://bitbucket.org/pypy/pypy/changeset/2e48ec813eda/
Log: Import float2longlong() from the jitypes2 branch, and use it in the
new FloatImmedLoc.
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -25,7 +25,7 @@
X86_64_XMM_SCRATCH_REG,
RegLoc, StackLoc, ConstFloatLoc,
ImmedLoc, AddressLoc, imm,
- imm0, imm1)
+ imm0, imm1, FloatImmedLoc)
from pypy.rlib.objectmodel import we_are_translated, specialize
from pypy.jit.backend.x86 import rx86, regloc, codebuf
@@ -1170,8 +1170,13 @@
self.mc.MOV16(dest_addr, value_loc)
elif size == 4:
self.mc.MOV32(dest_addr, value_loc)
- elif IS_X86_64 and size == 8:
- self.mc.MOV(dest_addr, value_loc)
+ elif size == 8:
+ if IS_X86_64:
+ self.mc.MOV(dest_addr, value_loc)
+ else:
+ assert isinstance(value_loc, FloatImmedLoc)
+ self.mc.MOV(dest_addr, value_loc.low_part_loc())
+ self.mc.MOV(dest_addr.add_offset(4), value_loc.high_part_loc())
else:
not_implemented("save_into_mem size = %d" % size)
diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/longlong2float.py
@@ -0,0 +1,47 @@
+"""
+This module exposes the functions longlong2float() and float2longlong(),
+which cast the bit pattern of a long long into a float and back.
+"""
+from pypy.rpython.lltypesystem import lltype, rffi
+
+
+# -------- implement longlong2float and float2longlong --------
+DOUBLE_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.DOUBLE))
+LONGLONG_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.LONGLONG))
+
+# these definitions are used only in tests, when not translated
+def longlong2float_emulator(llval):
+ d_array = lltype.malloc(DOUBLE_ARRAY_PTR.TO, 1, flavor='raw')
+ ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
+ ll_array[0] = llval
+ floatval = d_array[0]
+ lltype.free(d_array, flavor='raw')
+ return floatval
+
+def float2longlong_emulator(floatval):
+ d_array = lltype.malloc(DOUBLE_ARRAY_PTR.TO, 1, flavor='raw')
+ ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
+ d_array[0] = floatval
+ llval = ll_array[0]
+ lltype.free(d_array, flavor='raw')
+ return llval
+
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+eci = ExternalCompilationInfo(post_include_bits=["""
+static double pypy__longlong2float(long long x) {
+ return *((double*)&x);
+}
+static long long pypy__float2longlong(double x) {
+ return *((long long*)&x);
+}
+"""])
+
+longlong2float = rffi.llexternal(
+ "pypy__longlong2float", [rffi.LONGLONG], rffi.DOUBLE,
+ _callable=longlong2float_emulator, compilation_info=eci,
+ _nowrapper=True, pure_function=True)
+
+float2longlong = rffi.llexternal(
+ "pypy__float2longlong", [rffi.DOUBLE], rffi.LONGLONG,
+ _callable=float2longlong_emulator, compilation_info=eci,
+ _nowrapper=True, pure_function=True)
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -3,7 +3,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.jit.backend.x86.arch import WORD, IS_X86_32, IS_X86_64
from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib.objectmodel import specialize
+from pypy.rlib.objectmodel import specialize, instantiate
from pypy.rlib.rarithmetic import intmask
from pypy.jit.metainterp.history import FLOAT
@@ -175,6 +175,19 @@
return edx
return eax
+ def add_offset(self, ofs):
+ result = instantiate(AddressLoc)
+ result._location_code = self._location_code
+ if self._location_code == 'm':
+ result.loc_m = (self.loc_m[0], self.loc_m[1] + ofs)
+ elif self._location_code == 'a':
+ result.loc_a = self.loc_a[:3] + (self.loc_a[3] + ofs,)
+ elif self._location_code == 'j':
+ result.value = self.value + ofs
+ else:
+ raise AssertionError(self._location_code)
+ return result
+
class ConstFloatLoc(AssemblerLocation):
# XXX: We have to use this class instead of just AddressLoc because
# we want a width of 8 (... I think. Check this!)
@@ -190,6 +203,40 @@
def location_code(self):
return 'j'
+class FloatImmedLoc(AssemblerLocation):
+ # This stands for an immediate float. It cannot be directly used in
+ # any assembler instruction. Instead, it is meant to be decomposed
+ # in two 32-bit halves. On 64-bit, only use low_part(), which is
+ # actually everything.
+ _immutable_ = True
+ width = 8
+
+ def __init__(self, floatvalue):
+ from pypy.rlib.longlong2float import float2longlong
+ self.aslonglong = float2longlong(floatvalue)
+
+ def low_part(self):
+ return intmask(self.aslonglong)
+
+ def high_part(self):
+ assert IS_X86_32
+ return intmask(self.aslonglong >> 32)
+
+ def low_part_loc(self):
+ return ImmedLoc(self.low_part())
+
+ def high_part_loc(self):
+ return ImmedLoc(self.high_part())
+
+ def __repr__(self):
+ from pypy.rlib.longlong2float import longlong2float
+ floatvalue = longlong2float(self.aslonglong)
+ return '<FloatImmedLoc(%s)>' % (floatvalue,)
+
+ def location_code(self):
+ raise NotImplementedError
+
+
REGLOCS = [RegLoc(i, is_xmm=False) for i in range(16)]
XMMREGLOCS = [RegLoc(i, is_xmm=True) for i in range(16)]
eax, ecx, edx, ebx, esp, ebp, esi, edi, r8, r9, r10, r11, r12, r13, r14, r15 = REGLOCS
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -4,7 +4,7 @@
import os
from pypy.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr,
- ResOperation, BoxPtr, BoxFloat,
+ ResOperation, BoxPtr, ConstFloat,
LoopToken, INT, REF, FLOAT)
from pypy.jit.backend.x86.regloc import *
from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi, rstr
@@ -212,8 +212,8 @@
def make_sure_var_in_reg(self, var, forbidden_vars=[],
selected_reg=None, need_lower_byte=False):
if var.type == FLOAT:
- assert isinstance(var, BoxFloat), (
- "ConstFloats must be handled differently")
+ if isinstance(var, ConstFloat):
+ return FloatImmedLoc(var.getfloat())
return self.xrm.make_sure_var_in_reg(var, forbidden_vars,
selected_reg, need_lower_byte)
else:
More information about the Pypy-commit
mailing list