[pypy-svn] r36738 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
arigo at codespeak.net
arigo at codespeak.net
Sun Jan 14 15:11:50 CET 2007
Author: arigo
Date: Sun Jan 14 15:11:16 2007
New Revision: 36738
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Some more operations.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sun Jan 14 15:11:16 2007
@@ -1,4 +1,4 @@
-import sys
+import sys, py
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
@@ -64,7 +64,7 @@
emit = staticmethod(I386CodeBuilder.NEG)
class OpIntInvert(UnaryOp):
- opname = 'int_invert'
+ opname = 'int_invert', 'uint_invert'
emit = staticmethod(I386CodeBuilder.NOT)
class OpIntAbs(Op1):
@@ -169,24 +169,24 @@
mc.MOV(dstop, ecx)
class OpIntAdd(BinaryOp):
- opname = 'int_add'
+ opname = 'int_add', 'uint_add'
emit = staticmethod(I386CodeBuilder.ADD)
commutative = True
class OpIntSub(BinaryOp):
- opname = 'int_sub'
+ opname = 'int_sub', 'uint_sub'
emit = staticmethod(I386CodeBuilder.SUB)
class OpIntAnd(BinaryOp):
- opname = 'int_and'
+ opname = 'int_and', 'uint_and'
emit = staticmethod(I386CodeBuilder.AND)
class OpIntOr(BinaryOp):
- opname = 'int_or'
+ opname = 'int_or', 'uint_or'
emit = staticmethod(I386CodeBuilder.OR)
class OpIntXor(BinaryOp):
- opname = 'int_xor'
+ opname = 'int_xor', 'uint_xor'
emit = staticmethod(I386CodeBuilder.XOR)
class OpIntMul(Op2):
@@ -209,35 +209,61 @@
if dstop != tmpop:
mc.MOV(dstop, tmpop)
-class OpIntFloorDiv(Op2):
- opname = 'int_floordiv'
- divmod_result_register = eax
+class MulOrDivOp(Op2):
def generate3(self, mc, dstop, op1, op2):
- # not very efficient but not a very common operation either
+ # not very efficient but not very common operations either
if dstop != eax:
mc.PUSH(eax)
if dstop != edx:
mc.PUSH(edx)
if op1 != eax:
mc.MOV(eax, op1)
- mc.CDQ()
+ if self.input_is_64bits:
+ mc.CDQ()
try:
- mc.IDIV(op2)
+ self.emit(mc, op2)
except FailedToImplement:
mc.MOV(ecx, op2)
- mc.IDIV(ecx)
- mc.MOV(dstop, self.divmod_result_register)
+ self.emit(mc, ecx)
+ if dstop != self.reg_containing_result:
+ mc.MOV(dstop, self.reg_containing_result)
if dstop != edx:
mc.POP(edx)
if dstop != eax:
mc.POP(eax)
-class OpIntMod(OpIntFloorDiv):
+class OpIntFloorDiv(MulOrDivOp):
+ opname = 'int_floordiv'
+ input_is_64bits = True
+ reg_containing_result = eax
+ emit = staticmethod(I386CodeBuilder.IDIV)
+
+class OpIntMod(MulOrDivOp):
opname = 'int_mod'
- divmod_result_register = edx
+ input_is_64bits = True
+ reg_containing_result = edx
+ emit = staticmethod(I386CodeBuilder.IDIV)
+
+class OpUIntMul(MulOrDivOp):
+ opname = 'uint_mul'
+ input_is_64bits = False
+ reg_containing_result = eax
+ emit = staticmethod(I386CodeBuilder.MUL)
+
+class OpUIntFloorDiv(MulOrDivOp):
+ opname = 'uint_floordiv'
+ input_is_64bits = True
+ reg_containing_result = eax
+ emit = staticmethod(I386CodeBuilder.DIV)
+
+class OpUIntMod(MulOrDivOp):
+ opname = 'uint_mod'
+ input_is_64bits = True
+ reg_containing_result = edx
+ emit = staticmethod(I386CodeBuilder.DIV)
class OpIntLShift(Op2):
- opname = 'int_lshift'
+ opname = 'int_lshift', 'uint_lshift'
def generate3(self, mc, dstop, op1, op2):
# XXX not optimized
mc.MOV(ecx, op2)
@@ -267,6 +293,22 @@
mc.POP(dstop)
mc.SAR(dstop, cl)
+class OpUIntRShift(Op2):
+ opname = 'uint_rshift'
+ def generate3(self, mc, dstop, op1, op2):
+ # XXX not optimized
+ mc.MOV(ecx, op2)
+ if dstop != op1:
+ try:
+ mc.MOV(dstop, op1)
+ except FailedToImplement:
+ mc.PUSH(op1)
+ mc.POP(dstop)
+ mc.SHR(dstop, cl)
+ mc.CMP(ecx, imm8(32))
+ mc.SBB(ecx, ecx)
+ mc.AND(dstop, ecx)
+
class OpCompare2(Op2):
result_kind = RK_CC
def generate(self, allocator):
@@ -281,27 +323,27 @@
mc.CMP(ecx, dstop)
class OpIntLt(OpCompare2):
- opname = 'int_lt'
+ opname = 'int_lt', 'char_lt'
cc_result = Conditions['L']
class OpIntLe(OpCompare2):
- opname = 'int_le'
+ opname = 'int_le', 'char_le'
cc_result = Conditions['LE']
class OpIntEq(OpCompare2):
- opname = 'int_eq'
+ opname = 'int_eq', 'char_eq', 'unichar_eq'
cc_result = Conditions['E']
class OpIntNe(OpCompare2):
- opname = 'int_ne'
+ opname = 'int_ne', 'char_ne', 'unichar_ne'
cc_result = Conditions['NE']
class OpIntGt(OpCompare2):
- opname = 'int_gt'
+ opname = 'int_gt', 'char_gt'
cc_result = Conditions['G']
class OpIntGe(OpCompare2):
- opname = 'int_ge'
+ opname = 'int_ge', 'char_ge'
cc_result = Conditions['GE']
class JumpIf(Operation):
@@ -392,6 +434,22 @@
mc.MOV(dstop, eax)
mc.POP(eax)
+def field_operand(mc, base, fieldtoken):
+ # may use ecx
+ fieldoffset, fieldsize = fieldtoken
+
+ if isinstance(base, MODRM):
+ mc.MOV(ecx, base)
+ base = ecx
+ elif isinstance(base, IMM32):
+ fieldoffset += base.value
+ base = None
+
+ if fieldsize == 1:
+ return mem8(base, fieldoffset)
+ else:
+ return mem (base, fieldoffset)
+
def array_item_operand(mc, base, arraytoken, opindex):
# may use ecx
_, startoffset, itemoffset = arraytoken
@@ -434,7 +492,7 @@
self.varsizealloctoken = varsizealloctoken
self.gv_length = gv_length
def allocate(self, allocator):
- self.using(self.gv_length)
+ allocator.using(self.gv_length)
def generate(self, allocator):
dstop = allocator.get_operand(self)
srcop = allocator.get_operand(self.gv_length)
@@ -446,7 +504,7 @@
mc.LEA(ecx, op_size)
mc.MOV(dstop, ecx)
-def hard_store(mc, opmemtarget, opvalue, itemsize=WORD):
+def hard_store(mc, opmemtarget, opvalue, itemsize):
# For the possibly hard cases of stores
# Generates a store to 'opmemtarget' of size 'itemsize' == 1, 2 or 4.
# If it is 1, opmemtarget must be a MODRM8; otherwise, it must be a MODRM.
@@ -499,7 +557,7 @@
if must_pop_eax:
mc.POP(eax)
-def hard_load(mc, opdst, opmemsource, itemsize=WORD):
+def hard_load(mc, opdst, opmemsource, itemsize):
# For the possibly hard cases of stores
# Generates a load from 'opmemsource' of size 'itemsize' == 1, 2 or 4.
# If it is 1, opmemtarget must be a MODRM8; otherwise, it must be a MODRM.
@@ -527,11 +585,11 @@
mc.MOV(opdst, ecx)
class OpGetField(Operation):
- def __init__(self, fieldtoken, gv_ptr, gv_value):
+ def __init__(self, fieldtoken, gv_ptr):
self.fieldtoken = fieldtoken
- self.gv_ptr = gv_ptr
+ self.gv_ptr = gv_ptr
def allocate(self, allocator):
- self.using(self.gv_ptr)
+ allocator.using(self.gv_ptr)
def generate(self, allocator):
try:
dstop = allocator.get_operand(self)
@@ -539,11 +597,8 @@
return # result not used
opptr = allocator.get_operand(self.gv_ptr)
mc = allocator.mc
- if not isinstance(opptr, REG):
- mc.MOV(ecx, opptr)
- opptr = ecx
- offset, fieldsize = self.fieldtoken
- opsource = mem(opptr, offset)
+ opsource = field_operand(mc, opptr, self.fieldtoken)
+ _, fieldsize = self.fieldtoken
hard_load(mc, dstop, opsource, fieldsize)
class OpSetField(Operation):
@@ -553,17 +608,14 @@
self.gv_ptr = gv_ptr
self.gv_value = gv_value
def allocate(self, allocator):
- self.using(self.gv_ptr)
- self.using(self.gv_value)
+ allocator.using(self.gv_ptr)
+ allocator.using(self.gv_value)
def generate(self, allocator):
opptr = allocator.get_operand(self.gv_ptr)
opvalue = allocator.get_operand(self.gv_value)
mc = allocator.mc
- if not isinstance(opptr, REG):
- mc.MOV(ecx, opptr)
- opptr = ecx
- offset, fieldsize = self.fieldtoken
- optarget = mem(opptr, offset)
+ optarget = field_operand(mc, opptr, self.fieldtoken)
+ _, fieldsize = self.fieldtoken
hard_store(mc, optarget, opvalue, fieldsize)
class OpGetArrayItem(Operation):
@@ -572,8 +624,8 @@
self.gv_array = gv_array
self.gv_index = gv_index
def allocate(self, allocator):
- self.using(self.gv_array)
- self.using(self.gv_index)
+ allocator.using(self.gv_array)
+ allocator.using(self.gv_index)
def generate(self, allocator):
try:
dstop = allocator.get_operand(self)
@@ -583,7 +635,7 @@
opindex = allocator.get_operand(self.gv_index)
mc = allocator.mc
opsource = array_item_operand(mc, oparray, self.arraytoken, opindex)
- _, _, itemsize = arraytoken
+ _, _, itemsize = self.arraytoken
hard_load(mc, dstop, opsource, itemsize)
class OpSetArrayItem(Operation):
@@ -594,16 +646,16 @@
self.gv_index = gv_index
self.gv_value = gv_value
def allocate(self, allocator):
- self.using(self.gv_array)
- self.using(self.gv_index)
- self.using(self.gv_value)
+ allocator.using(self.gv_array)
+ allocator.using(self.gv_index)
+ allocator.using(self.gv_value)
def generate(self, allocator):
oparray = allocator.get_operand(self.gv_array)
opindex = allocator.get_operand(self.gv_index)
opvalue = allocator.get_operand(self.gv_value)
mc = allocator.mc
optarget = array_item_operand(mc, oparray, self.arraytoken, opindex)
- _, _, itemsize = arraytoken
+ _, _, itemsize = self.arraytoken
hard_store(mc, optarget, opvalue, itemsize)
# ____________________________________________________________
@@ -738,9 +790,12 @@
d = {}
for name, value in globals().items():
if type(value) is type(base) and issubclass(value, base):
- if hasattr(value, 'opname'):
- assert value.opname not in d
- d[value.opname] = value
+ opnames = getattr(value, 'opname', ())
+ if isinstance(opnames, str):
+ opnames = (opnames,)
+ for opname in opnames:
+ assert opname not in d
+ d[opname] = value
return d
OPCLASSES1 = setup_opclasses(Op1)
OPCLASSES2 = setup_opclasses(Op2)
@@ -748,17 +803,11 @@
# identity operations
OPCLASSES1['cast_bool_to_int'] = None
+OPCLASSES1['cast_char_to_int'] = None
+OPCLASSES1['cast_unichar_to_int'] = None
OPCLASSES1['cast_int_to_char'] = None
OPCLASSES1['cast_int_to_unichar'] = None
-# synonyms
-OPCLASSES2['char_lt'] = OPCLASSES2['int_lt']
-OPCLASSES2['char_le'] = OPCLASSES2['int_le']
-OPCLASSES2['char_eq'] = OPCLASSES2['unichar_eq'] = OPCLASSES2['int_eq']
-OPCLASSES2['char_ne'] = OPCLASSES2['unichar_ne'] = OPCLASSES2['int_ne']
-OPCLASSES2['char_gt'] = OPCLASSES2['int_gt']
-OPCLASSES2['char_ge'] = OPCLASSES2['int_ge']
-
def setup_conditions():
result1 = [None] * 16
result2 = [None] * 16
More information about the Pypy-commit
mailing list