Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r74794:4634aad50952 Date: 2014-12-03 11:29 +0100 http://bitbucket.org/pypy/pypy/changeset/4634aad50952/
Log: Add INT_SIGNEXT to test_random, and found out another corner case on 32-bit only. diff --git a/rpython/jit/backend/test/test_random.py b/rpython/jit/backend/test/test_random.py --- a/rpython/jit/backend/test/test_random.py +++ b/rpython/jit/backend/test/test_random.py @@ -321,6 +321,14 @@ else: self.put(builder, [ConstFloat(r.random_float_storage())]) +class SignExtOperation(AbstractOperation): + def produce_into(self, builder, r): + sizes = [1, 2] + if sys.maxint > (1 << 32): + sizes.append(4) + self.put(builder, [r.choice(builder.intvars), + ConstInt(r.choice(sizes))]) + class BinaryOperation(AbstractOperation): def __init__(self, opnum, and_mask=-1, or_mask=0, boolres=False): AbstractOperation.__init__(self, opnum, boolres=boolres) @@ -509,6 +517,7 @@ OPERATIONS.append(UnaryOperation(rop.INT_IS_TRUE, boolres=True)) OPERATIONS.append(UnaryOperation(rop.INT_IS_ZERO, boolres=True)) OPERATIONS.append(ConstUnaryOperation(rop.SAME_AS, boolres='sometimes')) +OPERATIONS.append(SignExtOperation(rop.INT_SIGNEXT)) for _op in [rop.INT_ADD_OVF, rop.INT_SUB_OVF, diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1147,9 +1147,20 @@ def genop_int_signext(self, op, arglocs, resloc): argloc, numbytesloc = arglocs assert isinstance(numbytesloc, ImmedLoc) + assert isinstance(resloc, RegLoc) if numbytesloc.value == 1: if isinstance(argloc, RegLoc): - argloc = argloc.lowest8bits() + if WORD == 4 and argloc.value >= 4: + # meh, can't read the lowest byte of esi or edi on 32-bit + if resloc.value < 4: + self.mc.MOV(resloc, argloc) + argloc = resloc + else: + tmploc = RawEspLoc(0, INT) + self.mc.MOV(tmploc, argloc) + argloc = tmploc + if isinstance(argloc, RegLoc): + argloc = argloc.lowest8bits() self.mc.MOVSX8(resloc, argloc) elif numbytesloc.value == 2: self.mc.MOVSX16(resloc, argloc) diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -151,6 +151,8 @@ def lowest8bits(self): assert not self.is_xmm + if WORD == 4: + assert 0 <= self.value < 4 return RegLoc(rx86.low_byte(self.value), False) def higher8bits(self): diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py --- a/rpython/jit/backend/x86/rx86.py +++ b/rpython/jit/backend/x86/rx86.py @@ -33,8 +33,9 @@ xmmnames = ['xmm%d' % i for i in range(16)] def low_byte(reg): - # XXX: On 32-bit, this only works for 0 <= reg < 4 - # Maybe we should check this? + # On 32-bit, this only works for 0 <= reg < 4. The caller checks that. + # On 64-bit, it works for any register, but the assembler instruction + # must include a REX prefix (possibly with no modifier flags). return reg | BYTE_REG_FLAG def high_byte(reg): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit