Esempio n. 1
0
def _mul16(ins):
    ''' Multiplies tow last 16bit values on top of the stack and
    and returns the value on top of the stack

    Optimizations:
      * If any of the ops is ZERO,
        then do A = 0 ==> XOR A, cause A * 0 = 0 * A = 0

      * If any ot the ops is ONE, do NOTHING
        A * 1 = 1 * A = A

      * If B is 2^n and B < 16 => Shift Right n
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:   # If any of the operands is constant
        op1, op2 = _int_ops(op1, op2)    # put the constant one the 2nd
        output = _16bit_oper(op1)

        if op2 == 0: # A * 0 = 0 * A = 0
            if op1[0] in ('_', '$'):
                output = [] # Optimization: Discard previous op if not from the stack
            output.append('ld hl, 0')
            output.append('push hl')
            return output

        if op2 == 1: # A * 1 = 1 * A == A => Do nothing
            output.append('push hl')
            return output 

        if op2 == 0xFFFF: # This is the same as (-1)
            output.append('call __NEGHL')
            output.append('push hl')
            REQUIRES.add('neg16.asm')
            return output

        if is_2n(op2) and log2(op2) < 4:
            output.extend(['add hl, hl'] * int(log2(op2)))
            output.append('push hl')
            return output

        output.append('ld de, %i' % op2)
    else:
        if op2[0] == '_': # stack optimization
            op1, op2 = op2, op1

        output = _16bit_oper(op1, op2)

    output.append('call __MUL16_FAST') # Inmmediate
    output.append('push hl')
    REQUIRES.add('mul16.asm')
    return output
Esempio n. 2
0
def _modi8(ins):
    ''' Reminder of div. 2 8bit unsigned integers. The result is pushed onto the stack.

    Optimizations:
      * If 2nd operands is 1 then
        returns 0

      * If 2nd operand = 2^n => do AND (2^n - 1)

    '''
    op1, op2 = tuple(ins.quad[2:])
    if is_int(op2):
        op2 = int8(op2)

        output = _8bit_oper(op1)
        if op2 == 1:
            if op1[0] == '_':
                output = [
                ]  # Optimization: Discard previous op if not from the stack

            output.append('xor a')
            output.append('push af')
            return output

        if is_2n(op2):
            output.append('and %i' % (op2 - 1))
            output.append('push af')
            return output

        output.append('ld h, %i' % int8(op2))
    else:
        if op2[0] == '_':  # Optimization when 2nd operand is an id
            if is_int(op1) and int(op1) == 0:
                output = [
                ]  # Optimization: Discard previous op if not from the stack
                output.append('xor a')
                output.append('push af')
                return output

            rev = True
            op1, op2 = op2, op1
        else:
            rev = False

        output = _8bit_oper(op1, op2, rev)

    output.append('call __MODI8_FAST')
    output.append('push af')
    REQUIRES.add('div8.asm')
    return output
Esempio n. 3
0
def _modi8(ins):
    ''' Reminder of div. 2 8bit unsigned integers. The result is pushed onto the stack.

    Optimizations:
      * If 2nd operands is 1 then
        returns 0

      * If 2nd operand = 2^n => do AND (2^n - 1)

    '''
    op1, op2 = tuple(ins.quad[2:])
    if is_int(op2):
        op2 = int8(op2)

        output = _8bit_oper(op1)
        if op2 == 1:
            if op1[0] == '_':
                output = [] # Optimization: Discard previous op if not from the stack

            output.append('xor a')
            output.append('push af')
            return output

        if is_2n(op2):
            output.append('and %i' % (op2 - 1))
            output.append('push af')
            return output

        output.append('ld h, %i' % int8(op2))
    else:
        if op2[0] == '_': # Optimization when 2nd operand is an id
            if is_int(op1) and int(op1) == 0:
                output = [] # Optimization: Discard previous op if not from the stack
                output.append('xor a')
                output.append('push af')
                return output

            rev = True
            op1, op2 = op2, op1
        else:
            rev = False

        output = _8bit_oper(op1, op2, rev)

    output.append('call __MODI8_FAST')
    output.append('push af')
    REQUIRES.add('div8.asm')
    return output
Esempio n. 4
0
def _modi16(ins):
    ''' Reminder of div 2 16bit signed integers. The result is pushed onto the stack.

        Optimizations:
         * If 2nd operand is 1 => Return 0
         * If 2nd operand = 2^n => do AND (2^n - 1)
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_int(op2):
        op2 = int16(op2)
        output = _16bit_oper(op1)

        if op2 == 1:
            if op2[0] in ('_', '$'):
                output = [] # Optimization: Discard previous op if not from the stack

            output.append('ld hl, 0')
            output.append('push hl')
            return output

        if is_2n(op2):
            k = op2 - 1
            if op2 > 255: # only affects H
                output.append('ld a, h')
                output.append('and %i' % (k >> 8))
                output.append('ld h, a')
            else:
                output.append('ld h, 0') # High part goes 0
                output.append('ld a, l')
                output.append('and %i' % (k % 0xFF))
                output.append('ld l, a')

            output.append('push hl')
            return output

        output.append('ld de, %i' % op2)
    else:
        output = _16bit_oper(op1, op2)

    output.append('call __MODI16')
    output.append('push hl')
    REQUIRES.add('div16.asm')
    return output