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
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
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
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