Example #1
0
def _band8(ins):
    ''' Pops top 2 operands out of the stack, and does
        1st AND (bitwise) 2nd operand (top of the stack),
        pushes the result.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0xFF:  # X & 0xFF = X
            output.append('push af')
            return output

        if op2 == 0:  # X and 0 = 0
            output.append('xor a')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('and h')
    output.append('push af')
    REQUIRES.add('and8.asm')

    return output
Example #2
0
def _xor8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand XOR (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)  # True or X = not X
        if op2 == 0:  # False xor X = X
            output.append('push af')
            return output

        output.append('sub 1')
        output.append('sbc a, a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('call __XOR8')
    output.append('push af')
    REQUIRES.add('xor8.asm')

    return output
Example #3
0
def _and8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand AND (logical) 2nd operand (top of the stack),
        pushes 0 if False, not 0 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)  # Pops the stack (if applicable)
        if op2 != 0:  # X and True = X
            output.append('push af')
            return output

        # False and X = False
        output.append('xor a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('call __AND8')
    output.append('push af')
    REQUIRES.add('and8.asm')

    return output
Example #4
0
def _bor8(ins):
    ''' pops top 2 operands out of the stack, and does
        OR (bitwise) with 1st and 2nd operand (top of the stack),
        pushes result.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:  # X | 0 = X
            output.append('push af')
            return output

        if op2 == 0xFF:  # X | 0xFF = 0xFF
            output.append('ld a, 0FFh')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('or h')
    output.append('push af')

    return output
Example #5
0
def _or8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand OR (logical) 2nd operand (top of the stack),
        pushes 0 if False, not 0 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:  # X or False = X
            output.append('push af')
            return output

        # X or True = True
        output.append('ld a, 1')  # True
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('or h')
    output.append('push af')

    return output
Example #6
0
def _bxor8(ins):
    ''' Pops top 2 operands out of the stack, and does
        1st operand XOR (bitwise) 2nd operand (top of the stack),
        pushes the result

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:  # 0 xor X = X
            output.append('push af')
            return output

        if op2 == 0xFF:  # X xor 0xFF = ~X
            output.append('cpl')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('xor h')
    output.append('push af')

    return output
Example #7
0
def _and16(ins):
    ''' Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand AND (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        16 bit un/signed version

        Optimizations:

        If any of the operators are constants: Returns either 0 or
        the other operand
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _16bit_oper(op1)
        if op2 != 0:
            output.append('ld a, h')
            output.append('or l')
            output.append('push af')
            return output # X and True = X

        output = _16bit_oper(op1)
        output.append('xor a') # X and False = False
        output.append('push af')
        return output

    output = _16bit_oper(op1, op2)
    output.append('call __AND16')
    output.append('push af')
    REQUIRES.add('and16.asm')
    return output
Example #8
0
def _and32(ins):
    ''' Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand AND (Logical) 2nd operand (top of the stack).
        Pushes 0 if False, 1 if True. 

        32 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2):
        op1, op2 = _int_ops(op1, op2)
        
        if op2 == 0:    # X and False = False
            if str(op1)[0] == 't': # a temporary term (stack)
                output = _32bit_oper(op1) # Remove op1 from the stack
            else:
                output = []
            output.append('xor a')
            output.append('push af')
            return output

        # For X and TRUE = X we do nothing as we have to convert it to boolean
        # which is a rather expensive instruction

    output = _32bit_oper(op1, op2)
    output.append('call __AND32')
    output.append('push af')
    REQUIRES.add('and32.asm')
    return output
Example #9
0
def _and8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand AND (logical) 2nd operand (top of the stack),
        pushes 0 if False, not 0 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1) # Pops the stack (if applicable)
        if op2 != 0:    # X and True = X
            output.append('push af')
            return output
    
        # False and X = False
        output.append('xor a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('call __AND8')
    output.append('push af')
    REQUIRES.add('and8.asm')

    return output
Example #10
0
def _band8(ins):
    ''' Pops top 2 operands out of the stack, and does
        1st AND (bitwise) 2nd operand (top of the stack),
        pushes the result.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1) 
        if op2 == 0xFF: # X & 0xFF = X
            output.append('push af')
            return output

        if op2 == 0:    # X and 0 = 0
            output.append('xor a')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('and h')
    output.append('push af')
    REQUIRES.add('and8.asm')

    return output
Example #11
0
def _bxor16(ins):
    ''' Pops top 2 operands out of the stack, and performs
        1st operand XOR (bitwise) 2nd operand (top of the stack),
        pushes result (16 bit in HL).

        16 bit un/signed version

        Optimizations:

        If any of the operators are constants: Returns either 0 or
        the other operand
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _16bit_oper(op1)
        if op2 == 0: # X ^ 0 = X
            output.append('push hl')
            return output

        if op2 == 0xFFFF: # X ^ 0xFFFF = bNOT X
            output.append('call __NEGHL')
            output.append('push hl')
            REQUIRES.add('neg16.asm')
            return output

    output = _16bit_oper(op1, op2)
    output.append('call __BXOR16')
    output.append('push hl')
    REQUIRES.add('bxor16.asm')
    return output
Example #12
0
def _bor8(ins):
    ''' pops top 2 operands out of the stack, and does
        OR (bitwise) with 1st and 2nd operand (top of the stack),
        pushes result.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:    # X | 0 = X
            output.append('push af')
            return output

        if op2 == 0xFF: # X | 0xFF = 0xFF
            output.append('ld a, 0FFh')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('or h')
    output.append('push af')

    return output
Example #13
0
def _band16(ins):
    ''' Pops top 2 operands out of the stack, and performs
        1st operand AND (bitwise) 2nd operand (top of the stack),
        pushes result (16 bit in HL).

        16 bit un/signed version

        Optimizations:

        If any of the operators are constants: Returns either 0 or
        the other operand
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        if op2 == 0xFFFF: # X & 0xFFFF = X
            return []

        if op2 == 0: # X & 0 = 0
            output = _16bit_oper(op1)
            output.append('ld hl, 0')
            output.append('push hl')
            return output

    output = _16bit_oper(op1, op2)
    output.append('call __BAND16')
    output.append('push hl')
    REQUIRES.add('band16.asm')
    return output
Example #14
0
def _bxor8(ins):
    ''' Pops top 2 operands out of the stack, and does
        1st operand XOR (bitwise) 2nd operand (top of the stack),
        pushes the result

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1) 
        if op2 == 0:    # 0 xor X = X
            output.append('push af')
            return output

        if op2 == 0xFF: # X xor 0xFF = ~X
            output.append('cpl')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('xor h')
    output.append('push af')

    return output
Example #15
0
def _mul32(ins):
    ''' Multiplies two last 32bit values on top of the stack and
    and returns the value on top of the stack

    Optimizations done:
    
        * If any operand is 1, do nothing
        * If any operand is 0, push 0
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2):
        op1, op2 = _int_ops(op1, op2)
        output = _32bit_oper(op1)

        if op2 == 1:
            output.append('push de')
            output.append('push hl')
            return output    # A * 1 = Nothing

        if op2 == 0:
            output.append('ld hl, 0')
            output.append('push hl')
            output.append('push hl')
            return output

    output = _32bit_oper(op1, op2)
    output.append('call __MUL32') # Inmmediate
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('mul32.asm')
    return output
Example #16
0
def _xor8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand XOR (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)    # True or X = not X
        if op2 == 0:    # False xor X = X
            output.append('push af')
            return output

        output.append('sub 1')
        output.append('sbc a, a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('call __XOR8')
    output.append('push af')
    REQUIRES.add('xor8.asm')

    return output
Example #17
0
def _or8(ins):
    ''' Pops top 2 operands out of the stack, and checks
        if 1st operand OR (logical) 2nd operand (top of the stack),
        pushes 0 if False, not 0 if True.

        8 bit un/signed version
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:    # X or False = X
            output.append('push af')
            return output

        # X or True = True
        output.append('ld a, 1')    # True
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('or h')
    output.append('push af')

    return output
Example #18
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
Example #19
0
def _mul8(ins):
    ''' Multiplies 2 las values from 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
    '''

    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 1: # A * 1 = 1 * A = A
            output.append('push af')
            return output

        if op2 == 0:
            output.append('xor a')
            output.append('push af')
            return output

        if op2 == 2: # A * 2 == A SLA 1
            output.append('add a, a')
            output.append('push af')
            return output

        if op2 == 4: # A * 4 == A SLA 2
            output.append('add a, a')
            output.append('add a, a')
            output.append('push af')
            return output

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

        output = _8bit_oper(op1, op2)

    output.append('call __MUL8_FAST') # Inmmediate
    output.append('push af')
    REQUIRES.add('mul8.asm')
    return output
Example #20
0
def _add8(ins):
    ''' Pops last 2 bytes from the stack and adds them.
    Then push the result onto the stack.

    Optimizations:
      * If any of the operands is ZERO,
        then do NOTHING: A + 0 = 0 + A = A

      * If any of the operands is 1, then
        INC is used

      * If any of the operands is -1 (255), then
        DEC is used
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:    # Nothing to add: A + 0 = A
            output.append('push af')
            return output

        op2 = int8(op2)

        if op2 == 1: # Adding 1 is just an inc
            output.append('inc a')
            output.append('push af')
            return output

        if op2 == 0xFF: # Adding 255 is just a dec
            output.append('dec a')
            output.append('push af')
            return output

        output.append('add a, %i' % int8(op2))
        output.append('push af')
        return output

    if op2[0] == '_': # stack optimization
        op1, op2 = op2, op1

    output = _8bit_oper(op1, op2)
    output.append('add a, h')
    output.append('push af')

    return output
Example #21
0
def _mul8(ins):
    ''' Multiplies 2 las values from 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
    '''

    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 1:  # A * 1 = 1 * A = A
            output.append('push af')
            return output

        if op2 == 0:
            output.append('xor a')
            output.append('push af')
            return output

        if op2 == 2:  # A * 2 == A SLA 1
            output.append('add a, a')
            output.append('push af')
            return output

        if op2 == 4:  # A * 4 == A SLA 2
            output.append('add a, a')
            output.append('add a, a')
            output.append('push af')
            return output

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

        output = _8bit_oper(op1, op2)

    output.append('call __MUL8_FAST')  # Inmmediate
    output.append('push af')
    REQUIRES.add('mul8.asm')
    return output
Example #22
0
def _add8(ins):
    ''' Pops last 2 bytes from the stack and adds them.
    Then push the result onto the stack.

    Optimizations:
      * If any of the operands is ZERO,
        then do NOTHING: A + 0 = 0 + A = A

      * If any of the operands is 1, then
        INC is used

      * If any of the operands is -1 (255), then
        DEC is used
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:  # Nothing to add: A + 0 = A
            output.append('push af')
            return output

        op2 = int8(op2)

        if op2 == 1:  # Adding 1 is just an inc
            output.append('inc a')
            output.append('push af')
            return output

        if op2 == 0xFF:  # Adding 255 is just a dec
            output.append('dec a')
            output.append('push af')
            return output

        output.append('add a, %i' % int8(op2))
        output.append('push af')
        return output

    if op2[0] == '_':  # stack optimization
        op1, op2 = op2, op1

    output = _8bit_oper(op1, op2)
    output.append('add a, h')
    output.append('push af')

    return output
Example #23
0
def _add16(ins):
    ''' Pops last 2 bytes from the stack and adds them.
    Then push the result onto the stack.


    Optimizations:
      * If any of the operands is ZERO,
        then do NOTHING: A + 0 = 0 + A = A

      * If any of the operands is < 4, then
        INC is used

      * If any of the operands is > (65531) (-4), then
        DEC is used
    '''
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)
        op2 = int16(op2)
        output = _16bit_oper(op1)

        if op2 == 0:
            output.append('push hl')
            return output # ADD HL, 0 => NOTHING

        if op2 < 4:
            output.extend(['inc hl'] * op2) #  ADD HL, 2 ==> inc hl; inc hl
            output.append('push hl')
            return output

        if op2 > 65531: # (between -4 and 0)
            output.extend(['dec hl'] * (0x10000 - op2))
            output.append('push hl')
            return output

        output.append('ld de, %i' % op2)
        output.append('add hl, de')
        output.append('push hl')
        return output

    if op2[0] == '_': # stack optimization
        op1, op2 = op2, op1
    
    output = _16bit_oper(op1, op2)
    output.append('add hl, de')
    output.append('push hl')
    return output
Example #24
0
def _add32(ins):
    ''' Pops last 2 bytes from the stack and adds them.
    Then push the result onto the stack.

    Optimizations:
      * If any of the operands is ZERO,
        then do NOTHING: A + 0 = 0 + A = A
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        o1, o2 = _int_ops(op1, op2)

        if int(o2) == 0: # A + 0 = 0 + A = A => Do Nothing
            output = _32bit_oper(o1)
            output.append('push de')
            output.append('push hl')
            return output

    if op1[0] == '_' and op2[0] != '_':
        op1, op2 = op2, op1 # swap them

    if op2[0] == '_':
        output = _32bit_oper(op1)
        output.append('ld bc, (%s)' % op2)
        output.append('add hl, bc')
        output.append('ex de, hl')
        output.append('ld bc, (%s + 2)' % op2)
        output.append('adc hl, bc')
        output.append('push hl')
        output.append('push de')
        return output

    output = _32bit_oper(op1, op2)
    output.append('pop bc')
    output.append('add hl, bc')
    output.append('ex de, hl')
    output.append('pop bc')
    output.append('adc hl, bc')
    output.append('push hl') # High and low parts are reversed
    output.append('push de')

    return output
Example #25
0
def _xor16(ins):
    ''' Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand XOR (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        16 bit un/signed version

        Optimizations:

        If any of the operators are constants: Returns either 0 or
        the other operand
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)
        output = _16bit_oper(op1)

        if op2 == 0: # X xor False = X 
            output.append('ld a, h')
            output.append('or l')
            output.append('push af')
            return output 

        # X xor True = NOT X
        output.append('ld a, h')
        output.append('or l')
        output.append('sub 1')
        output.append('sbc a, a')
        output.append('push af')
        return output

    output = _16bit_oper(ins.quad[2], ins.quad[3])
    output.append('call __XOR16')
    output.append('push af')
    REQUIRES.add('xor16.asm')
    return output
Example #26
0
def _or16(ins):
    ''' Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand OR (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        16 bit un/signed version

        Optimizations:

        If any of the operators are constants: Returns either 0 or
        the other operand
    '''
    op1, op2 = tuple(ins.quad[2:])

    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        if op2 == 0:
            output = _16bit_oper(op1)
            output.append('ld a, h')
            output.append('or l') # Convert x to Boolean
            output.append('push af')
            return output # X or False = X

        output = _16bit_oper(op1)
        output.append('ld a, 0FFh') # X or True = True
        output.append('push af')
        return output

    output = _16bit_oper(ins.quad[2], ins.quad[3])
    output.append('ld a, h')
    output.append('or l')
    output.append('or d')
    output.append('or e')
    output.append('push af')
    return output