[pypy-commit] pypy arm-backend-2: start implementing the long long support

bivab noreply at buildbot.pypy.org
Thu Apr 5 14:19:04 CEST 2012


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r54198:7dbbed165924
Date: 2012-03-27 12:23 +0000
http://bitbucket.org/pypy/pypy/changeset/7dbbed165924/

Log:	start implementing the long long support

diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -925,6 +925,19 @@
             return False
         return True
 
+    def regalloc_emit_llong(self, op, arglocs, fcond, regalloc):
+        effectinfo = op.getdescr().get_extra_info()
+        oopspecindex = effectinfo.oopspecindex
+        asm_llong_operations[oopspecindex](self, op, arglocs, regalloc, fcond)
+	return fcond 
+
+    def regalloc_emit_math(self, op, arglocs, fcond, regalloc):
+        effectinfo = op.getdescr().get_extra_info()
+        oopspecindex = effectinfo.oopspecindex
+        asm_math_operations[oopspecindex](self, op, arglocs, resloc)
+        return fcond
+
+
     def _insert_checks(self, mc=None):
         if not we_are_translated() and self._debug:
             if mc is None:
@@ -1265,6 +1278,7 @@
 
 asm_operations = [notimplemented_op] * (rop._LAST + 1)
 asm_operations_with_guard = [notimplemented_op_with_guard] * (rop._LAST + 1)
+asm_llong_operations = {}
 asm_math_operations = {}
 
 for name, value in ResOpAssembler.__dict__.iteritems():
diff --git a/pypy/jit/backend/arm/instruction_builder.py b/pypy/jit/backend/arm/instruction_builder.py
--- a/pypy/jit/backend/arm/instruction_builder.py
+++ b/pypy/jit/backend/arm/instruction_builder.py
@@ -350,6 +350,36 @@
             self.write32(instr)
     return f
 
+def define_simd_instructions_3regs_func(name, table):
+    n = 0x79 << 25
+    if 'A' in table:
+        n |= (table['A'] & 0xF) << 8
+    if 'B' in table:
+        n |= (table['B'] & 0x1) << 4
+    if 'U' in table:
+        n |= (table['U'] & 0x1) << 24
+    if 'C' in table:
+        n |= (table['C'] & 0x3) << 20
+    if name == 'VADD_i64' or name == 'VSUB_i64':
+        size = 0x3
+        n |= size << 20
+    def f(self, dd, dn, dm):
+	N = (dn >> 4) & 0x1
+	M = (dm >> 4) & 0x1
+	D = (dd >> 4) & 0x1
+	Q = 0 # we want doubleword regs
+        instr = (n
+                | D << 22
+                | (dn & 0xf) << 16
+                | (dd & 0xf) << 12
+                | N << 7
+                | Q << 6
+                | M << 5
+                | (dm & 0xf))
+	
+        self.write32(instr)
+    return f
+
 
 def imm_operation(rt, rn, imm):
     return ((rn & 0xFF) << 16
@@ -368,6 +398,7 @@
 
 def define_instruction(builder, key, val, target):
     f = builder(key, val)
+    f.__name__ = key
     setattr(target, key, f)
 
 
@@ -378,7 +409,6 @@
             continue
         try:
             func = globals()['define_%s_func' % name]
-            func.__name__ = name
         except KeyError:
             print 'No instr generator for %s instructions' % name
             continue
diff --git a/pypy/jit/backend/arm/instructions.py b/pypy/jit/backend/arm/instructions.py
--- a/pypy/jit/backend/arm/instructions.py
+++ b/pypy/jit/backend/arm/instructions.py
@@ -140,3 +140,11 @@
     'VSQRT' : {'opc1':0xB, 'opc2':0x1, 'opc3':0x3, 'base': False},
     #'VCVT' : {'opc1':0xB, 'opc2':0xE, 'opc3':0x1, 'base': False},
 }
+
+simd_instructions_3regs = {
+    'VADD_i64': {'A': 0x8, 'B': 0, 'U': 0},
+    'VSUB_i64': {'A': 0x8, 'B': 0, 'U': 1},
+    'VAND_i64': {'A': 0x1, 'B': 1, 'U': 0, 'C': 0},
+    'VORR_i64': {'A': 0x1, 'B': 1, 'U': 0, 'C': 0x10},
+    'VEOR_i64': {'A': 0x1, 'B': 1, 'U': 1, 'C': 0x0},
+}
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -1282,4 +1282,9 @@
         self.mc.VCVT_int_to_float(res.value, temp.value)
         return fcond
 
+    emit_op_llong_add = gen_emit_float_op('llong_add', 'VADD_i64')
+    emit_op_llong_sub = gen_emit_float_op('llong_sub', 'VSUB_i64')
+    emit_op_llong_and = gen_emit_float_op('llong_and', 'VAND_i64')
+    emit_op_llong_or = gen_emit_float_op('llong_or', 'VORR_i64')
+    emit_op_llong_xor = gen_emit_float_op('llong_xor', 'VEOR_i64')
 
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -374,6 +374,12 @@
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
 
+    def perform_llong(self, op, args, fcond):
+        return self.assembler.regalloc_emit_llong(op, args, fcond, self)
+    
+    def perform_math(self, op, args, fcond):
+	return self.assembler.regalloc_emit_math(op, args, self, fcond)
+
     def force_spill_var(self, var):
         if var.type == FLOAT:
             self.vfprm.force_spill_var(var)
@@ -541,6 +547,18 @@
         effectinfo = op.getdescr().get_extra_info()
         if effectinfo is not None:
             oopspecindex = effectinfo.oopspecindex
+            if oopspecindex in (EffectInfo.OS_LLONG_ADD,
+            		    EffectInfo.OS_LLONG_SUB,
+            		    EffectInfo.OS_LLONG_AND,
+            		    EffectInfo.OS_LLONG_OR,
+            		    EffectInfo.OS_LLONG_XOR):
+                args = self._prepare_llong_binop_xx(op, fcond)
+		self.perform_llong(op, args, fcond)
+                return
+            if oopspecindex == EffectInfo.OS_LLONG_TO_INT:
+                args = self._prepare_llong_to_int(op, fcond)
+		self.perform_llong(op, args, fcond)
+                return
             if oopspecindex == EffectInfo.OS_MATH_SQRT:
                 args = self.prepare_op_math_sqrt(op, fcond)
                 self.perform_math(op, args, fcond)
@@ -568,6 +586,15 @@
     def prepare_op_call_malloc_gc(self, op, fcond):
         return self._prepare_call(op)
 
+    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))
+        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_guard(self, op, args=None):
         if args is None:
             args = []
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -9,6 +9,7 @@
 class ArmCPU(AbstractLLCPU):
 
     supports_floats = True
+    supports_longlong = True
 
     def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
                  gcdescr=None):


More information about the pypy-commit mailing list