[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