Example #1
0
def execute_bl(s, inst):
    if condition_passed(s, inst.cond):
        s.rf[LR] = trim_32(s.fetch_pc() + 4)
        offset = signed(sext_30(inst.imm_24) << 2)
        s.rf[PC] = trim_32(signed(s.rf[PC]) + offset)
        return
    s.rf[PC] = s.fetch_pc() + 4
Example #2
0
def execute_fmax_s(s, inst):
    a, b = trim_32(s.fp[inst.rs1]), trim_32(s.fp[inst.rs2])
    # TODO: s.fp[ inst.rd ] = sfp.isNaNF32UI(b) || ...
    s.fp[inst.rd] = a if sfp.f32_le_quiet(b, a) else b
    s.fcsr = sfp.get_flags()
    sfp.set_flags(0)
    s.pc += 4
Example #3
0
def execute_bl( s, inst ):
  if condition_passed( s, inst.cond ):
    s.rf[LR] = trim_32( s.fetch_pc() + 4 )
    offset   = signed( sext_30( inst.imm_24 ) << 2 )
    s.rf[PC] = trim_32( signed( s.rf[PC] ) + offset )
    return
  s.rf[PC] = s.fetch_pc() + 4
Example #4
0
def execute_fmax_s( s, inst ):
  a, b = trim_32( s.fp[inst.rs1] ), trim_32( s.fp[inst.rs2] )
  # TODO: s.fp[ inst.rd ] = sfp.isNaNF32UI(b) || ...
  s.fp[ inst.rd ] = a if sfp.f32_le_quiet(b,a) else b
  s.fcsr          = sfp.get_flags()
  sfp.set_flags( 0 )
  s.pc += 4
Example #5
0
def execute_sc_d(s, inst):
    addr = s.rf[inst.rs1]
    if addr == s.load_reservation:
        s.mem.write(addr, 4, trim_32(s.rf[inst.rs2]))
        s.mem.write(addr + 4, 4, trim_32(s.rf[inst.rs2] >> 32))
        s.rf[inst.rd] = 0
    else:
        s.rf[inst.rd] = 1
    s.pc += 4
Example #6
0
def execute_amoand_d(s, inst):
    addr = s.rf[inst.rs1]
    value = (( s.mem.read( addr+4, 4 ) << 32 ) \
             | s.mem.read( addr,   4 ))
    new = value & s.rf[inst.rs2]
    s.mem.write(addr, 4, trim_32(new))
    s.mem.write(addr + 4, 4, trim_32(new >> 32))
    s.rf[inst.rd] = value
    s.pc += 4
Example #7
0
def execute_amomax_d( s, inst ):
  addr  = s.rf[inst.rs1]
  value = (( s.mem.read( addr+4, 4 ) << 32 ) \
           | s.mem.read( addr,   4 ))
  new   = max( signed(value, 64), signed(s.rf[inst.rs2], 64) )
  s.mem.write( addr,   4, trim_32( new )       )
  s.mem.write( addr+4, 4, trim_32( new >> 32 ) )
  s.rf[inst.rd] = value
  s.pc += 4
Example #8
0
def execute_sc_d( s, inst ):
  addr = s.rf[inst.rs1]
  if addr == s.load_reservation:
    s.mem.write( addr,   4, trim_32( s.rf[inst.rs2] ) )
    s.mem.write( addr+4, 4, trim_32( s.rf[inst.rs2] >> 32 ) )
    s.rf[inst.rd] = 0
  else:
    s.rf[inst.rd] = 1
  s.pc += 4
Example #9
0
def execute_amoand_d( s, inst ):
  addr  = s.rf[inst.rs1]
  value = (( s.mem.read( addr+4, 4 ) << 32 ) \
           | s.mem.read( addr,   4 ))
  new   = value & s.rf[inst.rs2]
  s.mem.write( addr,   4, trim_32( new )       )
  s.mem.write( addr+4, 4, trim_32( new >> 32 ) )
  s.rf[inst.rd] = value
  s.pc += 4
Example #10
0
def execute_amomax_d(s, inst):
    addr = s.rf[inst.rs1]
    value = (( s.mem.read( addr+4, 4 ) << 32 ) \
             | s.mem.read( addr,   4 ))
    new = max(signed(value, 64), signed(s.rf[inst.rs2], 64))
    s.mem.write(addr, 4, trim_32(new))
    s.mem.write(addr + 4, 4, trim_32(new >> 32))
    s.rf[inst.rd] = value
    s.pc += 4
def test_execute_arith_shift_right_imm(rn, imm, is16bit):
    rd = 2
    state = new_state(rf0=trim_32(rn))
    instr = (opcode_factory.asr16_immediate(rd=rd, rn=0, imm=imm) if is16bit
             else opcode_factory.asr32_immediate(rd=rd, rn=0, imm=imm))
    name, executefn = decode(instr)
    executefn(state, Instruction(instr, None))
    expected_state = StateChecker(AZ=(False if rn < 0 else True), # 1 >> 5 == 0
                                  AV=0, AC=0,
                                  pc=((2 if is16bit else 4) + RESET_ADDR),
                                  rf2=(trim_32(-1) if rn < 0 else 0))
    expected_state.check(state)
def test_execute_logical_shift_right(rn, rm, is16bit):
    rd = 2
    state = new_state(rf0=trim_32(rn), rf1=trim_32(rm))
    instr = (opcode_factory.lsr16(rd=rd, rn=0, rm=1) if is16bit
             else opcode_factory.lsr32(rd=rd, rn=0, rm=1))
    name, executefn = decode(instr)
    executefn(state, Instruction(instr, None))
    expected_state = StateChecker(AZ=(False if rn < 0 else True), # 1 >> 5 == 0
                                  AV=0, AC=0,
                                  pc=((2 if is16bit else 4) + RESET_ADDR),
                                  rf2=(0b1111 if rn < 0 else 0))
    expected_state.check(state)
Example #13
0
def execute_trap16(s, inst):
    """The TRAP instruction causes the processor to halt and wait for external
    inputs. The immediate field within the instruction opcode is not processed
    by the hardware but can be used by software such as a debugger or
    operating system to find out the reason for the TRAP instruction.
    """
    import pydgin.syscalls
    syscall_funcs = {
        2:  pydgin.syscalls.syscall_open,
        3:  pydgin.syscalls.syscall_close,
        4:  pydgin.syscalls.syscall_read,
        5:  pydgin.syscalls.syscall_write,
        6:  pydgin.syscalls.syscall_lseek,
        7:  pydgin.syscalls.syscall_unlink,
        10: pydgin.syscalls.syscall_fstat,
        15: pydgin.syscalls.syscall_stat,
#       19: get_time_of_day,  # TODO r0 = time pointer, r1 = timezone pointer
        21: pydgin.syscalls.syscall_link,
    }
    # Undocumented traps: 0, 1, 2, 6. These are listed as "Reserved" in
    # the reference manual, but have been reported to appear in real programs.
    if inst.t5 == 0 or inst.t5 == 1 or inst.t5 == 2 or inst.t5 == 6:
        if inst.t5 == 0:  # Write.
            syscall_handler = syscall_funcs[5]
        elif inst.t5 == 1:  # Read.
            syscall_handler = syscall_funcs[4]
        elif inst.t5 == 2:  # Open.
            syscall_handler = syscall_funcs[2]
        else:  # Close.
            syscall_handler = syscall_funcs[3]
        retval, errno = syscall_handler(s, s.rf[0], s.rf[1], s.rf[2])
        s.rf[0] = trim_32(retval)
        s.rf[3] = errno
    elif inst.t5 == 3:  # Exit.
        syscall_handler = pydgin.syscalls.syscall_exit
        retval, errno = syscall_handler(s, s.rf[0], s.rf[1], s.rf[2])
    elif inst.t5 == 4:
        if s.debug.enabled('syscalls'):
            print 'TRAP: Assertion SUCCEEDED.'
    elif inst.t5 == 5:
        if s.debug.enabled('syscalls'):
            print 'TRAP: Assertion FAILED.'
    elif inst.t5 == 7: # Initiate system call.
        syscall_handler = syscall_funcs[s.rf[3]]
        retval, errno = syscall_handler(s, s.rf[0], s.rf[1], s.rf[2])
        # Undocumented:
        s.rf[0] = trim_32(retval)
        s.rf[3] = errno
    else:
        print ('WARNING: syscall not implemented: %d. Should be unreachable' %
               inst.t5)
    s.pc += 2
Example #14
0
def execute_bic( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, cout) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result       = a & trim_32(~b)
    s.rf[ inst.rd ] = trim_32( result )

    if inst.S:
      if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = cout

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #15
0
def execute_bic(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, cout) = s.rf[inst.rn], shifter_operand(s, inst)
        result = a & trim_32(~b)
        s.rf[inst.rd] = trim_32(result)

        if inst.S:
            if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = cout

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #16
0
 def execute_bcond(s, inst):
     """
     B<COND>:
         IF (Passed)<COND>)) then
         PC = PC + (SignExtend(SIMM) << 1)
     BL:
         LR = next PC;
         PC = PC + (SignExtend(SIMM) << 1)
     """
     if is16bit:
         inst.bits &= 0xFFFF
     cond = inst.cond
     imm = inst.bcond_imm
     if cond == 0 and imm == 0:
         raise RuntimeError(
             (
                 "Epiphany simulator caught infinite loop at runtime. "
                 + "Instruction at pc=%s is attempting to "
                 + "branch unconditionally to itself."
             )
             % hex(s.pc)
         )
     if cond == 0b1111:  # Branch and link (BL).
         s.rf[epiphany.isa.reg_map["LR"]] = s.pc + (2 if is16bit else 4)
     if condition_passed(s, cond):
         offset = (signed(sext_8(imm)) << 1) if is16bit else (signed(sext_24(imm)) << 1)
         s.pc = trim_32(s.pc + offset)
     else:
         s.pc += 2 if is16bit else 4
     s.debug_flags()
Example #17
0
def execute_adc(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = a + b + s.C
        s.rf[inst.rd] = trim_32(result)

        if inst.S:
            if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = carry_from(result)
            s.V = overflow_from_add(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #18
0
def execute_sbc(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = intmask(a - b - (not s.C))
        s.rf[inst.rd] = trim_32(result)

        if inst.S:
            if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = not_borrow_from(result)
            s.V = overflow_from_sub(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #19
0
def execute_div( s, inst ):
  x    = signed( s.rf[ inst.rs ] )
  y    = signed( s.rf[ inst.rt ] )
  sign = -1 if (x < 0)^(y < 0) else 1

  s.rf[ inst.rd ] = trim_32( abs(x) / abs(y) * sign )
  s.pc += 4
Example #20
0
def execute_adc( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result  = a + b + s.C
    s.rf[ inst.rd ] = trim_32( result )

    if inst.S:
      if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = carry_from( result )
      s.V = overflow_from_add( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #21
0
def execute_mvn( s, inst ):
  if condition_passed( s, inst.cond ):
    a, cout = shifter_operand( s, inst )
    result  = trim_32( ~a )
    s.rf[ inst.rd ] = result

    if inst.S:
      if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = cout
      s.V = s.V

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #22
0
def execute_sbc( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result  = intmask( a - b - (not s.C) )
    s.rf[ inst.rd ] = trim_32( result )

    if inst.S:
      if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = not_borrow_from( result )
      s.V = overflow_from_sub( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #23
0
def execute_mvn(s, inst):
    if condition_passed(s, inst.cond):
        a, cout = shifter_operand(s, inst)
        result = trim_32(~a)
        s.rf[inst.rd] = result

        if inst.S:
            if inst.rd == 15: raise FatalError('Writing SPSR not implemented!')
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = cout
            s.V = s.V

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #24
0
 def farith(s, inst):
     """
     RD = RN <OP> RM
     BN = RD[31]
     if (RD[30:0] == 0) { BZ=1 } else { BZ=0 }
     if (UnbiasedExponent(RD) > 127) { BUV=1 } else { BV=0 }
     if (UbiasedExponent(RD) < -126) { BUS=1 } else { BUS=BUS }
     if (RM or RN == NAN) { BIS=1 } else { BIS=BIS }
     BVS = BVS | BV;
     """
     if is16bit:
         inst.bits &= 0xffff
     rd = bits2float(s.rf[inst.rd])
     rn = bits2float(s.rf[inst.rn])
     rm = bits2float(s.rf[inst.rm])
     # Binary operations.
     if name == 'add':
         result = rn + rm
     elif name == 'sub':
         result = rn - rm
     elif name == 'mul':
         result = rn * rm
     elif name == 'madd':
         result = rd + (rn * rm)
     elif name == 'msub':
         result = rd - (rn * rm)
     # Unary operations.
     elif name == 'float':
         result = float(s.rf[inst.rn])
     elif name == 'fix':
         if math.isnan(rn): # FXIME
             result = 0xffffffff
         else:
             result = int(rn)
     elif name == 'abs':
         result = abs(rn)
     # 'result' is always a Python float.
     # RD = RN <OP> RM
     s.rf[inst.rd] = trim_32(result if name == 'fix' else float2bits(result))
     # BN = RD[31]
     s.BN = True if result < 0.0 else False
     # if (RD[30:0] == 0) { BZ=1 } else { BZ=0 }
     s.BZ = True if abs(result) < 0.0001 else False
     # if (UnbiasedExponent(RD) > 127) { BUV=1 } else { BV=0 }
     s.BUV = True if get_exponent(s.rf[inst.rd]) > 127 else False
     # if (UbiasedExponent(RD) < -126) { BUS=1 } else { BUS=BUS }
     if get_exponent(s.rf[inst.rd]) > 127:
         s.BUS = True
     # if (RM or RN == NAN) { BIS=1 } else { BIS=BIS }
     if ((is_unary and math.isnan(rn)) or
             (not is_unary) and
             (math.isnan(rn) or math.isnan(rm))):
         s.BIS = True
     # BVS = BVS | BV;
     s.BVS = s.BVS or s.BV
     s.debug_flags()
     s.pc += 2 if is16bit else 4
Example #25
0
def addressing_mode_2( s, inst ):

  # Immediate vs. Register Offset
  if not inst.I: index    = inst.imm_12
  else:           index, _ = shifter_operand_imm(s, inst)

  Rn          = s.rf[inst.rn]
  offset_addr = Rn + index if inst.U else Rn - index

  # Offset Addressing/Pre-Indexed Addressing vs. Post-Indexed Addressing
  if inst.P: addr = offset_addr
  else:        addr = Rn

  # Offset Addressing vs. Pre-/Post-Indexed Addressing
  if not (inst.P ^ inst.W):
    s.rf[inst.rn] = trim_32( offset_addr )

  return trim_32( addr )
Example #26
0
def addressing_mode_2(s, inst):

    # Immediate vs. Register Offset
    if not inst.I: index = inst.imm_12
    else: index, _ = shifter_operand_imm(s, inst)

    Rn = s.rf[inst.rn]
    offset_addr = Rn + index if inst.U else Rn - index

    # Offset Addressing/Pre-Indexed Addressing vs. Post-Indexed Addressing
    if inst.P: addr = offset_addr
    else: addr = Rn

    # Offset Addressing vs. Pre-/Post-Indexed Addressing
    if not (inst.P ^ inst.W):
        s.rf[inst.rn] = trim_32(offset_addr)

    return trim_32(addr)
Example #27
0
def execute_mov( s, inst ):
  if condition_passed( s, inst.cond ):
    if inst.rd == 15 and inst.S:
    # if not CurrentModeHasSPSR(): CPSR = SPSR
    # else:                        UNPREDICTABLE
      raise FatalError('UNPREDICTABLE in user and system mode!')

    result, cout = shifter_operand( s, inst )
    s.rf[ inst.rd ] = trim_32( result )

    if inst.S:
      s.N = (result >> 31)&1
      s.Z = trim_32( result ) == 0
      s.C = cout
      s.V = s.V

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #28
0
 def execute_jr(s, inst):
     """
     LR = PC + 2 (16 bit) 4 (32 bit)    JALR only.
     PC = RN;
     """
     if is16bit:
         inst.bits &= 0xffff
     if save_lr:
         s.rf[epiphany.isa.reg_map['LR']] = trim_32(s.pc + (2 if is16bit else 4))
     s.pc = s.rf[inst.rn]
Example #29
0
def execute_mov(s, inst):
    if condition_passed(s, inst.cond):
        if inst.rd == 15 and inst.S:
            # if not CurrentModeHasSPSR(): CPSR = SPSR
            # else:                        UNPREDICTABLE
            raise FatalError('UNPREDICTABLE in user and system mode!')

        result, cout = shifter_operand(s, inst)
        s.rf[inst.rd] = trim_32(result)

        if inst.S:
            s.N = (result >> 31) & 1
            s.Z = trim_32(result) == 0
            s.C = cout
            s.V = s.V

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #30
0
def execute_blx2(s, inst):
    if condition_passed(s, inst.cond):
        s.rf[LR] = trim_32(s.fetch_pc() + 4)
        s.T = s.rf[inst.rm] & 0x00000001
        s.rf[PC] = s.rf[inst.rm] & 0xFFFFFFFE
        if s.T:
            raise FatalError("Entering THUMB mode! Unsupported!")

    # no pc + 4 on success
    else:
        s.rf[PC] = s.fetch_pc() + 4
Example #31
0
def addressing_mode_4( s, inst ):

  IA = 0b01
  IB = 0b11
  DA = 0b00
  DB = 0b10

  mode   = (inst.P << 1) | inst.U
  Rn     = s.rf[ inst.rn ]
  nbytes = 4 * popcount( inst.register_list )

  if   mode == IA: start_addr, end_addr = Rn,          Rn+nbytes-4
  elif mode == IB: start_addr, end_addr = Rn+4,        Rn+nbytes
  elif mode == DA: start_addr, end_addr = Rn-nbytes+4, Rn
  else:            start_addr, end_addr = Rn-nbytes,   Rn-4

  if inst.W:
    s.rf[ inst.rn ] = trim_32( (Rn + nbytes) if inst.U else (Rn - nbytes) )

  return trim_32( start_addr ), trim_32( end_addr )
Example #32
0
def execute_blx2( s, inst ):
  if condition_passed( s, inst.cond ):
    s.rf[LR] = trim_32( s.fetch_pc() + 4 )
    s.T      = s.rf[ inst.rm ] & 0x00000001
    s.rf[PC] = s.rf[ inst.rm ] & 0xFFFFFFFE
    if s.T:
      raise FatalError( "Entering THUMB mode! Unsupported!")

  # no pc + 4 on success
  else:
    s.rf[PC] = s.fetch_pc() + 4
Example #33
0
def execute_smull( s, inst ):
  if condition_passed( s, inst.cond ):
    if inst.rd == 15: raise FatalError('UNPREDICTABLE')
    if inst.rm == 15: raise FatalError('UNPREDICTABLE')
    if inst.rs == 15: raise FatalError('UNPREDICTABLE')
    if inst.rn == 15: raise FatalError('UNPREDICTABLE')

    RdHi, RdLo  = inst.rn, inst.rd
    Rm,   Rs    = signed(s.rf[ inst.rm ]), signed(s.rf[ inst.rs ])
    result      = Rm * Rs

    if RdHi == RdLo: raise FatalError('UNPREDICTABLE')

    s.rf[ RdHi ] = trim_32( result >> 32 )
    s.rf[ RdLo ] = trim_32( result )

    if inst.S:
      s.N = (result >> 63)&1
      s.Z = result == 0
  s.rf[PC] = s.fetch_pc() + 4
Example #34
0
def addressing_mode_4(s, inst):

    IA = 0b01
    IB = 0b11
    DA = 0b00
    DB = 0b10

    mode = (inst.P << 1) | inst.U
    Rn = s.rf[inst.rn]
    nbytes = 4 * popcount(inst.register_list)

    if mode == IA: start_addr, end_addr = Rn, Rn + nbytes - 4
    elif mode == IB: start_addr, end_addr = Rn + 4, Rn + nbytes
    elif mode == DA: start_addr, end_addr = Rn - nbytes + 4, Rn
    else: start_addr, end_addr = Rn - nbytes, Rn - 4

    if inst.W:
        s.rf[inst.rn] = trim_32((Rn + nbytes) if inst.U else (Rn - nbytes))

    return trim_32(start_addr), trim_32(end_addr)
Example #35
0
def addressing_mode_3(s, inst):
    if inst.SH == 0b00:
        raise FatalError('Not a load/store instruction!')

    # Immediate vs. Register Offset
    if inst.B: index = (inst.imm_H << 4) | inst.imm_L
    else: index = s.rf[inst.rm]

    Rn = s.rf[inst.rn]
    offset_addr = Rn + index if inst.U else Rn - index

    # Offset Addressing/Pre-Indexed Addressing vs. Post-Indexed Addressing
    if inst.P: addr = offset_addr
    else: addr = Rn

    # Offset Addressing vs. Pre-/Post-Indexed Addressing
    if not (inst.P ^ inst.W):
        s.rf[inst.rn] = trim_32(offset_addr)

    return trim_32(addr)
Example #36
0
def addressing_mode_3( s, inst ):
  if inst.SH == 0b00:
    raise FatalError('Not a load/store instruction!')

  # Immediate vs. Register Offset
  if inst.B: index = (inst.imm_H << 4) | inst.imm_L
  else:        index = s.rf[inst.rm]

  Rn          = s.rf[inst.rn]
  offset_addr = Rn + index if inst.U else Rn - index

  # Offset Addressing/Pre-Indexed Addressing vs. Post-Indexed Addressing
  if inst.P: addr = offset_addr
  else:        addr = Rn

  # Offset Addressing vs. Pre-/Post-Indexed Addressing
  if not (inst.P ^ inst.W):
    s.rf[inst.rn] = trim_32( offset_addr )

  return trim_32( addr )
Example #37
0
def execute_umull(s, inst):
    if condition_passed(s, inst.cond):
        if inst.rd == 15: raise FatalError('UNPREDICTABLE')
        if inst.rm == 15: raise FatalError('UNPREDICTABLE')
        if inst.rs == 15: raise FatalError('UNPREDICTABLE')
        if inst.rn == 15: raise FatalError('UNPREDICTABLE')

        RdHi, RdLo = inst.rn, inst.rd
        Rm, Rs = s.rf[inst.rm], s.rf[inst.rs]
        result = Rm * Rs

        if RdHi == RdLo: raise FatalError('UNPREDICTABLE')

        s.rf[RdHi] = trim_32(result >> 32)
        s.rf[RdLo] = trim_32(result)

        if inst.S:
            s.N = (result >> 63) & 1
            s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0)
    s.rf[PC] = s.fetch_pc() + 4
Example #38
0
def execute_smlal(s, inst):
    if condition_passed(s, inst.cond):
        if inst.rd == 15: raise FatalError('UNPREDICTABLE')
        if inst.rm == 15: raise FatalError('UNPREDICTABLE')
        if inst.rs == 15: raise FatalError('UNPREDICTABLE')
        if inst.rn == 15: raise FatalError('UNPREDICTABLE')

        RdHi, RdLo = inst.rn, inst.rd
        Rm, Rs = signed(s.rf[inst.rm]), signed(s.rf[inst.rs])
        accumulate = (s.rf[RdHi] << 32) | s.rf[RdLo]
        result = (Rm * Rs) + signed(accumulate)

        if RdHi == RdLo: raise FatalError('UNPREDICTABLE')

        s.rf[RdHi] = trim_32(result >> 32)
        s.rf[RdLo] = trim_32(result)

        if inst.S:
            s.N = (result >> 63) & 1
            s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0)
    s.rf[PC] = s.fetch_pc() + 4
Example #39
0
def execute_smlal( s, inst ):
  if condition_passed( s, inst.cond ):
    if inst.rd == 15: raise FatalError('UNPREDICTABLE')
    if inst.rm == 15: raise FatalError('UNPREDICTABLE')
    if inst.rs == 15: raise FatalError('UNPREDICTABLE')
    if inst.rn == 15: raise FatalError('UNPREDICTABLE')

    RdHi, RdLo  = inst.rn, inst.rd
    Rm,   Rs    = signed(s.rf[ inst.rm ]), signed(s.rf[ inst.rs ])
    accumulate  = (s.rf[ RdHi ] << 32) | s.rf[ RdLo ]
    result      = (Rm * Rs) + signed( accumulate )

    if RdHi == RdLo: raise FatalError('UNPREDICTABLE')

    s.rf[ RdHi ] = trim_32( result >> 32 )
    s.rf[ RdLo ] = trim_32( result )

    if inst.S:
      s.N = (result >> 63)&1
      s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0)
  s.rf[PC] = s.fetch_pc() + 4
Example #40
0
def test_single_inst_sub32():
    from pydgin.utils import trim_32
    instructions = [(opcode_factory.sub32_immediate(rd=1, rn=0, imm=0b01010101010), 32),
                    (opcode_factory.bkpt16(), 16)]
    epiphany = MockEpiphany()
    epiphany.init_state(instructions, rf0=5)
    assert epiphany.state.running
    epiphany.run()
    expected_state = StateChecker(AZ=0, AN=1, AC=0,
                                  pc=(6 + RESET_ADDR), rf1=trim_32(5 - 0b01010101010))
    expected_state.check(epiphany.state)
    assert not epiphany.state.running
Example #41
0
def execute_tst(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, cout) = s.rf[inst.rn], shifter_operand(s, inst)
        result = trim_32(a & b)

        if inst.S:
            s.N = (result >> 31) & 1
            s.Z = result == 0
            s.C = cout

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #42
0
def execute_cmp( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result = intmask( a - b )

    s.N = (result >> 31)&1
    s.Z = trim_32( result ) == 0
    s.C = not_borrow_from( result )
    s.V = overflow_from_sub( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #43
0
def execute_cmn(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = a + b

        s.N = (result >> 31) & 1
        s.Z = trim_32(result) == 0
        s.C = carry_from(result)
        s.V = overflow_from_add(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #44
0
def execute_cmn( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result = a + b

    s.N = (result >> 31)&1
    s.Z = trim_32( result ) == 0
    s.C = carry_from( result )
    s.V = overflow_from_add( a, b, result )

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #45
0
def execute_cmp(s, inst):
    if condition_passed(s, inst.cond):
        a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst)
        result = intmask(a - b)

        s.N = (result >> 31) & 1
        s.Z = trim_32(result) == 0
        s.C = not_borrow_from(result)
        s.V = overflow_from_sub(a, b, result)

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #46
0
def execute_tst( s, inst ):
  if condition_passed( s, inst.cond ):
    a, (b, cout) = s.rf[ inst.rn ], shifter_operand( s, inst )
    result = trim_32( a & b )

    if inst.S:
      s.N = (result >> 31)&1
      s.Z = result == 0
      s.C = cout

    if inst.rd == 15:
      return
  s.rf[PC] = s.fetch_pc() + 4
Example #47
0
 def execute_bit(s, inst):
     """RD = RN <OP> RM
     AN = RD[31]
     AV = 0
     AC = 0
     If ( RD[31:0] == 0 ) { AZ=1 } else { AZ=0 }
     """
     if is16bit:
         inst.bits &= 0xffff
     rm = inst.imm5 if imm else s.rf[inst.rm]
     if name == "and":
         result = s.rf[inst.rn] & rm
     elif name == "orr":
         result = s.rf[inst.rn] | rm
     elif name == "eor":
         result = s.rf[inst.rn] ^ rm
     elif name == "asr":
         result = signed(s.rf[inst.rn]) >> rm
     elif name == "lsr":
         result = s.rf[inst.rn] >> rm
     elif name == "lsl":
         result = s.rf[inst.rn] << rm
     elif name == "bitr":
         # The description of this instruction is confused in the ISA
         # reference. The decode table states that the instruction always
         # takes an intermediate, but the description of the instruction
         # states that it does not.
         result = 0
         for i in range(32):
             if (s.rf[inst.rn] & (1 << i)):
                 result |= (1 << (32 - 1 - i))
     s.rf[inst.rd] = trim_32(result)
     s.AN = bool((result >> 31) & 1)
     s.AC = False
     s.AV = False
     s.AZ = True if trim_32(result) == 0 else False
     s.debug_flags()
     s.pc += 2 if is16bit else 4
Example #48
0
def shifter_operand_reg(s, inst):
    shift_op = inst.shift
    Rm = s.rf[inst.rm]
    Rs = s.rf[inst.rs] & 0xFF

    out = cout = 0

    if shift_op == LOGIC_SHIFT_LEFT:
        if Rs == 0:
            out, cout = Rm, s.C
        elif Rs < 32:
            out, cout = Rm << Rs, (Rm >> 32 - Rs) & 1
        elif Rs == 32:
            out, cout = 0, (Rm) & 1
        elif Rs > 32:
            out, cout = 0, 0

    elif shift_op == LOGIC_SHIFT_RIGHT:
        if Rs == 0:
            out, cout = Rm, s.C
        elif Rs < 32:
            out, cout = Rm >> Rs, (Rm >> (Rs - 1)) & 1
        elif Rs == 32:
            out, cout = 0, (Rm >> 31) & 1
        elif Rs > 32:
            out, cout = 0, 0

    elif shift_op == ARITH_SHIFT_RIGHT:
        if Rs == 0:
            out, cout = Rm, s.C
        elif Rs < 32:
            out = arith_shift(Rm, Rs)
            cout = (Rm >> (Rs - 1)) & 1
        elif Rs >= 32:
            out = 0 if ((Rm >> 31) == 0) else 0xFFFFFFFF
            cout = (Rm >> 31) & 1

    elif shift_op == ROTATE_RIGHT:
        Rs4 = Rs & 0b1111
        if Rs == 0:
            out, cout = Rm, s.C
        elif Rs4 == 0:
            out, cout = Rm, (Rm >> 31) & 1
        elif Rs4 > 0:
            out, cout = rotate_right(Rm, Rs4), (Rm >> Rs4 - 1) & 1

    else:
        raise FatalError("Impossible shift_op!")

    return trim_32(out), cout
Example #49
0
def test_single_inst_sub32():
    from pydgin.utils import trim_32
    instructions = [(opcode_factory.sub32_immediate(rd=1, rn=0, imm=0b01010101010), 32),
                    (opcode_factory.trap16(3), 16)]
    revelation = MockRevelation()
    revelation.init_state(instructions, rf0=5)
    assert revelation.states[0x808].running
    exit_code, ticks = revelation.run()
    expected_state = StateChecker(AZ=0, AN=1, AC=0,
                                  pc=(6 + RESET_ADDR), rf1=trim_32(5 - 0b01010101010))
    expected_state.check(revelation.states[0x808])
    assert EXIT_SUCCESS == exit_code
    assert len(instructions) == ticks
    assert not revelation.states[0x808].running
Example #50
0
def execute_mul(s, inst):
    if condition_passed(s, inst.cond):
        Rm, Rs = s.rf[inst.rm], s.rf[inst.rs]
        result = trim_32(Rm * Rs)
        s.rf[inst.rn] = result

        if inst.S:
            if inst.rn == 15: raise FatalError('UNPREDICTABLE')
            if inst.rm == 15: raise FatalError('UNPREDICTABLE')
            if inst.rs == 15: raise FatalError('UNPREDICTABLE')
            s.N = (result >> 31) & 1
            s.Z = result == 0

        if inst.rd == 15:
            return
    s.rf[PC] = s.fetch_pc() + 4
Example #51
0
def execute_mla(s, inst):
    if condition_passed(s, inst.cond):
        if inst.rd == 15: raise FatalError('UNPREDICTABLE')
        if inst.rm == 15: raise FatalError('UNPREDICTABLE')
        if inst.rs == 15: raise FatalError('UNPREDICTABLE')
        if inst.rn == 15: raise FatalError('UNPREDICTABLE')

        Rm, Rs, Rd = s.rf[inst.rm], s.rf[inst.rs], s.rf[inst.rd]
        result = trim_32(Rm * Rs + Rd)
        s.rf[inst.rn] = result

        if inst.S:
            s.N = (result >> 31) & 1
            s.Z = result == 0

    s.rf[PC] = s.fetch_pc() + 4
Example #52
0
def do_syscall(s):
    syscall_number = s.rf[v4]
    arg0 = intmask(s.rf[a1])
    arg1 = intmask(s.rf[a2])
    arg2 = intmask(s.rf[a3])

    if syscall_number not in syscall_funcs:
        print "WARNING: syscall not implemented: %d" % syscall_number
        # TODO: return an error?
    else:
        syscall_handler = syscall_funcs[syscall_number]

        # call the syscall handler and get the return and error values
        retval, errno = syscall_handler(s, arg0, arg1, arg2)

        if s.debug.enabled("syscalls"):
            print " retval=%x errno=%x" % (retval, errno)

        s.rf[a1] = trim_32(retval)
Example #53
0
def multhi64(a, b):
    # returns the high 64 bits of 64 bit multiplication
    # using this trick to get the high bits of 64-bit multiplication:
    # http://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
    a_hi, a_lo = trim_32(a >> 32), trim_32(a)
    b_hi, b_lo = trim_32(b >> 32), trim_32(b)

    a_x_b_hi = a_hi * b_hi
    a_x_b_mid = a_hi * b_lo
    b_x_a_mid = b_hi * a_lo
    a_x_b_lo = a_lo * b_lo

    carry_bit = (trim_32(a_x_b_mid) + trim_32(b_x_a_mid) +
                 (a_x_b_lo >> 32)) >> 32

    return a_x_b_hi + (a_x_b_mid >> 32) + (b_x_a_mid >> 32) + carry_bit
Example #54
0
def shifter_operand_reg(s, inst):
    shift_op = inst.shift
    Rm = s.rf[inst.rm]
    Rs = s.rf[inst.rs] & 0xFF

    out = cout = 0

    if shift_op == LOGIC_SHIFT_LEFT:
        if Rs == 0: out, cout = Rm, s.C
        elif Rs < 32: out, cout = Rm << Rs, (Rm >> 32 - Rs) & 1
        elif Rs == 32: out, cout = 0, (Rm) & 1
        elif Rs > 32: out, cout = 0, 0

    elif shift_op == LOGIC_SHIFT_RIGHT:
        if Rs == 0: out, cout = Rm, s.C
        elif Rs < 32: out, cout = Rm >> Rs, (Rm >> (Rs - 1)) & 1
        elif Rs == 32: out, cout = 0, (Rm >> 31) & 1
        elif Rs > 32: out, cout = 0, 0

    elif shift_op == ARITH_SHIFT_RIGHT:
        if Rs == 0: out, cout = Rm, s.C
        elif Rs < 32:
            out = arith_shift(Rm, Rs)
            cout = (Rm >> (Rs - 1)) & 1
        elif Rs >= 32:
            out = 0 if ((Rm >> 31) == 0) else 0xFFFFFFFF
            cout = (Rm >> 31) & 1

    elif shift_op == ROTATE_RIGHT:
        Rs4 = Rs & 0b1111
        if Rs == 0: out, cout = Rm, s.C
        elif Rs4 == 0: out, cout = Rm, (Rm >> 31) & 1
        elif Rs4 > 0: out, cout = rotate_right(Rm, Rs4), (Rm >> Rs4 - 1) & 1

    else:
        raise FatalError('Impossible shift_op!')

    return trim_32(out), cout
Example #55
0
def shifter_operand_imm(s, inst):
    shift_op = inst.shift
    Rm = s.rf[inst.rm]
    shift_imm = inst.shift_amt
    assert 0 <= shift_imm <= 31

    if shift_op == LOGIC_SHIFT_LEFT:
        out = Rm if (shift_imm == 0) else Rm << shift_imm
        cout = s.C if (shift_imm == 0) else (Rm >> 32 - shift_imm) & 1

    elif shift_op == LOGIC_SHIFT_RIGHT:
        # NOTE: shift_imm == 0 signifies a shift by 32
        out = 0 if (shift_imm == 0) else Rm >> shift_imm
        cout = Rm >> 31 if (shift_imm == 0) else (Rm >> shift_imm - 1) & 1

    elif shift_op == ARITH_SHIFT_RIGHT:
        # NOTE: shift_imm == 0 signifies a shift by 32
        if shift_imm == 0:
            if (Rm >> 31) == 0: out, cout = 0, Rm >> 31
            else: out, cout = 0xFFFFFFFF, Rm >> 31
        else:
            out = arith_shift(Rm, shift_imm)
            cout = (Rm >> shift_imm - 1) & 1

    elif shift_op == ROTATE_RIGHT:
        # NOTE: shift_imm == 0 signifies a rotate right with extend (RRX)
        if shift_imm == 0:
            out = (r_uint(s.C) << 31) | (Rm >> 1)
            cout = Rm & 1
        else:
            out = rotate_right(Rm, shift_imm)
            cout = (Rm >> shift_imm - 1) & 1

    else:
        raise FatalError('Impossible shift_op!')

    return trim_32(out), cout
Example #56
0
def execute_trunc_w_s( s, inst ):
  # TODO: check for overflow
  x = bits2float( s.rf[ inst.fs ] )
  s.rf[ inst.fd ] = trim_32(int(x))  # round down
  s.pc += 4
Example #57
0
def execute_cvt_w_s( s, inst ):
  x = bits2float( s.rf[ inst.fs ] )
  s.rf[ inst.fd ] = trim_32( int( x ) )
  s.pc += 4
Example #58
0
def execute_amo_add( s, inst ):
  temp = s.mem.read( s.rf[ inst.rs ], 4 )
  s.mem.write( s.rf[inst.rs], 4, trim_32(temp + s.rf[inst.rt]) )
  s.rf[ inst.rd ] = temp
  s.pc += 4
Example #59
0
def execute_sb( s, inst ):
  addr = trim_32( s.rf[inst.rs] + sext_16(inst.imm) )
  s.mem.write( addr, 1, s.rf[inst.rt] )
  s.pc += 4