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 _pstoref(ins):
    ''' Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.
    '''
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4 # Return Address + "push IX" 

    output = _float_oper(value)
        
    if indirect:
        output.append('ld hl, %i' % I)
        output.append('call __PISTOREF')
        REQUIRES.add('storef.asm')
        return output

    # direct store
    output.append('ld hl, %i' % I)
    output.append('call __PSTOREF')
    REQUIRES.add('pstoref.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 _pstoref16(ins):
    ''' Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.
    '''
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    bytes = 3 
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4 # Return Address + "push IX" 

    output = _f16_oper(value)
    ix_changed = not (-128 + bytes <= I <= 127 - bytes) # Offset > 127 bytes. Need to change IX
        
    if indirect:
        output.append('ld bc, %i' % I)
        output.append('call __PISTORE32')
        REQUIRES.add('pistore32.asm')
        return output

    # direct store
    output.append('ld bc, %i' % I)
    output.append('call __PSTORE32')
    REQUIRES.add('pstore32.asm')

    return output
Example #5
0
def _astoref16(ins):
    ''' Stores 2º operand content into address of 1st operand.
    storef16 a, x =>  *(&a) = x
    '''
    output = _addr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    if indirect:
        output.append('push hl')
        output.extend(_f16_oper(ins.quad[2], useBC=True))
        output.append('pop hl')
        REQUIRES.add('iload32.asm')
    else:
        output.extend(_f16_oper(ins.quad[2], useBC=True))

    output.append('call __STORE32')
    REQUIRES.add('store32.asm')

    return output
Example #6
0
def _modf16(ins):
    ''' Reminder of div. 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd op is 1. Returns 0
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_int(op2):
        if int(op2) == 1:
            output = _f16b_opers(op1)
            output.append('ld hl, 0')
            output.append('push hl')
            output.append('push hl')
            return output

    rev = not is_float(op1) and op1[0] != 't' and op2[0] == 't'

    output = _f16_oper(op1, op2, reversed=rev)
    output.append('call __MODF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('modf16.asm')
    return output
Example #7
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 #8
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 #9
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 #10
0
def _divi32(ins):
    ''' Divides 2 32bit signed integers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd operand is 1, do nothing
         * If 2nd operand is -1, do NEG32
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_int(op2):
        if int(op2) == 1:
            output = _32bit_oper(op1)
            output.append('push de')
            output.append('push hl')
            return output

        if int(op2) == -1:
            return _neg32(ins)

    rev = is_int(op1) or op1[0] == 't' or op2[0] != 't'
    output = _32bit_oper(op1, op2, rev)
    output.append('call __DIVI32')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('div32.asm')
    return output
Example #11
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 #12
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 #13
0
def _astoref16(ins):
    ''' Stores 2º operand content into address of 1st operand.
    storef16 a, x =>  *(&a) = x
    '''
    output = _addr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    if indirect:
        output.append('push hl')
        output.extend(_f16_oper(ins.quad[2], useBC = True))
        output.append('pop hl')
        REQUIRES.add('iload32.asm')
    else:
        output.extend(_f16_oper(ins.quad[2], useBC = True))

    output.append('call __STORE32')
    REQUIRES.add('store32.asm')

    return output
Example #14
0
def _astore32(ins):
    ''' Stores 2º operand content into address of 1st operand.
    store16 a, x =>  *(&a) = x
    '''
    output = _addr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    try:
        value = int(ins.quad[2]) & 0xFFFFFFFF # Immediate?
        if indirect:
            output.append('push hl')
            output.append('ld hl, %i' % (value & 0xFFFF))
            output.append('call __ILOAD32')
            output.append('ld b, h')
            output.append('ld c, l') # BC = Lower 16 bits
            output.append('pop hl')
            REQUIRES.add('iload32.asm')
        else:
            output.append('ld de, %i' % (value >> 16))
            output.append('ld bc, %i' % (value & 0xFFFF))
    except ValueError:
        output.append('pop bc')
        output.append('pop de')

    output.append('call __STORE32')
    REQUIRES.add('store32.asm')

    return output
Example #15
0
def _pastore16(ins):
    ''' Stores 2º operand content into address of 1st operand.
    store16 a, x =>  *(&a) = x
    Use '*' for indirect store on 1st operand.
    '''
    output = _paddr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    try:
        value = int(ins.quad[2]) & 0xFFFF
        output.append('ld de, %i' % value)
        if indirect:
            output.append('call __LOAD_DE_DE')
            REQUIRES.add('lddede.asm')

    except ValueError:
        output.append('pop de')

    output.append('ld (hl), e')
    output.append('inc hl')
    output.append('ld (hl), d')

    return output
Example #16
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 #17
0
def _divf16(ins):
    ''' Divides 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd operand is 1, do nothing
         * If 2nd operand is -1, do NEG32
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_float(op2):
        if float(op2) == 1:
            output = _f16_oper(op1)
            output.append('push de')
            output.append('push hl')
            return output

        if float(op2) == -1:
            return _negf(ins)

    rev = not is_float(op1) and op1[0] != 't' and op2[0] == 't'

    output = _f16_oper(op1, op2, reversed=rev)
    output.append('call __DIVF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('divf16.asm')
    return output
Example #18
0
def _mulf16(ins):
    ''' Multiplies 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.
    '''
    op1, op2 = tuple(ins.quad[2:])

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

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

        if op2 == -1:
            return _neg32(ins)

        output = _f16_oper(op1)
        if op2 == 0:
            output.append('ld hl, 0')
            output.append('ld e, h')
            output.append('ld d, l')
            output.append('push de')
            output.append('push hl')
            return output

    output = _f16_oper(op1, str(op2))
    output.append('call __MULF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('mulf16.asm')
    return output
Example #19
0
def _divf16(ins):
    ''' Divides 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd operand is 1, do nothing
         * If 2nd operand is -1, do NEG32
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_float(op2):
        if float(op2) == 1:
            output = _f16_oper(op1)
            output.append('push de')
            output.append('push hl')
            return output

        if float(op2) == -1:
            return _negf(ins)

    rev = not is_float(op1) and op1[0] != 't' and op2[0] == 't'
    
    output = _f16_oper(op1, op2, reversed = rev)
    output.append('call __DIVF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('divf16.asm')
    return output
Example #20
0
def _modf16(ins):
    ''' Reminder of div. 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.

        Optimizations:

         * If 2nd op is 1. Returns 0
    '''
    op1, op2 = tuple(ins.quad[2:])

    if is_int(op2):
        if int(op2) == 1:
            output = _f16b_opers(op1)
            output.append('ld hl, 0')
            output.append('push hl')
            output.append('push hl')
            return output    
        
    rev = not is_float(op1) and op1[0] != 't' and op2[0] == 't'

    output = _f16_oper(op1, op2, reversed = rev)
    output.append('call __MODF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('modf16.asm')
    return output
Example #21
0
def _pastoref16(ins):
    ''' Stores 2º operand content into address of 1st operand.
    storef16 a, x =>  *(&a) = x
    '''
    output = _paddr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    try:
        if indirect:
            value = int(ins.quad[2])
            output.append('push hl')
            output.append('ld hl, %i' % (value & 0xFFFF))
            output.append('call __ILOAD32')
            output.append('ld b, h')
            output.append('ld c, l')  # BC = Lower 16 bits
            output.append('pop hl')
            REQUIRES.add('iload32.asm')
        else:
            de, hl = f16(value)
            output.append('ld de, %i' % de)
            output.append('ld bc, %i' % hl)
    except ValueError:
        output.append('pop bc')
        output.append('pop de')

    output.append('call __STORE32')
    REQUIRES.add('store32.asm')

    return output
Example #22
0
def _mulf16(ins):
    ''' Multiplies 2 32bit (16.16) fixed point numbers. The result is pushed onto the stack.
    '''
    op1, op2 = tuple(ins.quad[2:])

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

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

        if op2 == -1:
            return _neg32(ins)

        output = _f16_oper(op1)
        if op2 == 0:
            output.append('ld hl, 0')
            output.append('ld e, h')
            output.append('ld d, l')
            output.append('push de')
            output.append('push hl')
            return output
            
    output = _f16_oper(op1, str(op2))
    output.append('call __MULF16')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('mulf16.asm')
    return output
Example #23
0
def _pastore16(ins):
    ''' Stores 2º operand content into address of 1st operand.
    store16 a, x =>  *(&a) = x
    Use '*' for indirect store on 1st operand.
    '''
    output = _paddr(ins.quad[1])

    value = ins.quad[2]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    try:
        value = int(ins.quad[2]) & 0xFFFF
        output.append('ld de, %i' % value)
        if indirect:
            output.append('call __LOAD_DE_DE')
            REQUIRES.add('lddede.asm')

    except ValueError:
        output.append('pop de')

    output.append('ld (hl), e')
    output.append('inc hl')
    output.append('ld (hl), d')

    return output
Example #24
0
def _paddr(offset):
    ''' Generic array address parameter loading.
    Emmits output code for setting IX at the right location.
    bytes = Number of bytes to load:
        1 => 8 bit value
        2 => 16 bit value / string
        4 => 32 bit value / f16 value
        5 => 40 bit value
    '''
    output = []

    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output.append('push ix')
    output.append('pop hl')
    output.append('ld de, %i' % I)
    output.append('add hl, de')

    if indirect:
        output.append('ld c, (hl)')
        output.append('inc hl')
        output.append('ld h, (hl)')
        output.append('ld l, c')

    output.append('call __ARRAY')
    REQUIRES.add('array.asm')
    return output
Example #25
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 #26
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 #27
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 #28
0
def _paddr(offset):
    ''' Generic array address parameter loading.
    Emmits output code for setting IX at the right location.
    bytes = Number of bytes to load:
        1 => 8 bit value
        2 => 16 bit value / string
        4 => 32 bit value / f16 value
        5 => 40 bit value
    '''
    output = []

    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4 # Return Address + "push IX"

    output.append('push ix')
    output.append('pop hl')
    output.append('ld de, %i' % I)
    output.append('add hl, de')

    if indirect:
        output.append('ld c, (hl)')
        output.append('inc hl')
        output.append('ld h, (hl)')
        output.append('ld l, c')

    output.append('call __ARRAY')
    REQUIRES.add('array.asm')
    return output
Example #29
0
def _abs8(ins):
    ''' Absolute value of top of the stack (8 bits in AF)
    '''
    output = _8bit_oper(ins.quad[2])
    output.append('call __ABS8')
    output.append('push af')
    REQUIRES.add('abs8.asm')
    return output
Example #30
0
def _abs8(ins):
    ''' Absolute value of top of the stack (8 bits in AF)
    '''
    output = _8bit_oper(ins.quad[2])
    output.append('call __ABS8')
    output.append('push af')
    REQUIRES.add('abs8.asm')
    return output
Example #31
0
def _neg16(ins):
    ''' Negates top of the stack (16 bits in HL)
    '''
    output = _16bit_oper(ins.quad[2])
    output.append('call __NEGHL')
    output.append('push hl')
    REQUIRES.add('neg16.asm')
    return output
Example #32
0
def _bnot16(ins):
    ''' Negates top (Bitwise NOT) of the stack (16 bits in HL)
    '''
    output = _16bit_oper(ins.quad[2])
    output.append('call __BNOT16')
    output.append('push hl')
    REQUIRES.add('bnot16.asm')
    return output
Example #33
0
def _negf(ins):
    ''' Changes sign of top of the stack (48 bits)
    '''
    output = _float_oper(ins.quad[2])
    output.append('call __NEGF')
    output.extend(_fpush())
    REQUIRES.add('negf.asm')
    return output
Example #34
0
def _abs16(ins):
    ''' Absolute value of top of the stack (16 bits in HL)
    '''
    output = _16bit_oper(ins.quad[2])
    output.append('call __ABS16')
    output.append('push hl')
    REQUIRES.add('abs16.asm')
    return output
Example #35
0
def _not32(ins):
    ''' Negates top (Logical NOT) of the stack (32 bits in DEHL)
    '''
    output = _32bit_oper(ins.quad[2])
    output.append('call __NOT32')
    output.append('push af')
    REQUIRES.add('not32.asm')
    return output
Example #36
0
def _notf(ins):
    ''' Negates top of the stack (48 bits)
    '''
    output = _float_oper(ins.quad[2])
    output.append('call __NOTF')
    output.append('push af')
    REQUIRES.add('notf.asm')
    return output
Example #37
0
def _divi16(ins):
    ''' Divides 2 16bit signed integers. The result is pushed onto the stack.

    Optimizations:
      * If 2nd op is 1 then
        do nothing

      * If 2nd op is -1 then
        do NEG

      * If 2nd op is 2 then
        Shift Right Arithmetic
    '''
    op1, op2 = tuple(ins.quad[2:])
    if is_int(op1) and int(op1) == 0: # 0 / A = 0

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

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

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

        if op == 1:
            output.append('push hl')
            return output

        if op == -1:
            output.append('call __NEGHL')
            output.append('push hl')
            REQUIRES.add('neg16.asm')
            return output

        if op == 2:
            output.append('sra h')
            output.append('rr l')
            output.append('push hl')
            return output

        output.append('ld de, %i' % op)
    else:
        if op2[0] == '_': # Optimization when 2nd operand is an id
            rev = True
            op1, op2 = op2, op1
        else:
            rev = False
        output = _16bit_oper(op1, op2, rev)

    output.append('call __DIVI16')
    output.append('push hl')
    REQUIRES.add('div16.asm')
    return output
Example #38
0
def _modf(ins):
    ''' Reminder of div. 2 float values. The result is pushed onto the stack.
    '''
    op1, op2 = tuple(ins.quad[2:])
    output = _float_oper(op1, op2)
    output.append('call __MODF')
    output.extend(_fpush())
    REQUIRES.add('modf.asm')
    return output
Example #39
0
def _abs32(ins):
    ''' Absolute value of top of the stack (32 bits in DEHL)
    '''
    output = _32bit_oper(ins.quad[2])
    output.append('call __ABS32')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('abs32.asm')
    return output
Example #40
0
def _neg32(ins):
    ''' Negates top of the stack (32 bits in DEHL)
    '''
    output = _32bit_oper(ins.quad[2])
    output.append('call __NEG32')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('neg32.asm')
    return output
Example #41
0
def _bnot32(ins):
    ''' Negates top (Bitwise NOT) of the stack (32 bits in DEHL)
    '''
    output = _32bit_oper(ins.quad[2])
    output.append('call __BNOT32')
    output.append('push de')
    output.append('push hl')
    REQUIRES.add('bnot32.asm')
    return output