Exemple #1
0
    def run(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        a, err = state.getReg(arg2)
        if isinstance(arg3, str):
            if err is None:
                b, err = state.getReg(arg3)
            else:
                b, _ = state.getReg(arg3)

            if b > 32:
                return state, programState.RunError(f"Shift value is out of range: value must be below 33 but is {b}", programState.RunError.ErrorType.Error)
        else:
            b = arg3

        out = a >> b
        out32 = out & 0xFFFF_FFFF

        if ((a >> 31) & 1) == 1:  # sign-extend
            out32 |= (0xFFFF_FFFF << (32 - b)) & 0xFFFF_FFFF

        if b == 0:
            c = state.status.C  # The C flag is unaffected if the shift value is 0 - ARM docs
        else:
            c = bool((a >> (b-1)) & 1)  # Get last bit shifted out

        n = bool((out32 >> 31) & 1)
        z = out32 == 0

        state.setReg(arg1, out32)
        state.setALUState(programState.StatusRegister(n, z, c, False))

        return state, err
def branchToLabel(state: programState.ProgramState, label: str) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
    # Save return address in LR
    state.setReg("LR", state.getReg("PC"))

    address: Union[int, programState.RunError] = state.getLabelAddress(label)
    if isinstance(address, programState.RunError):
        return state, programState.RunError(f"Unknown startup label: {label}", programState.RunError.ErrorType.Error)
    else:
        # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4
        state.setReg("PC", address - 4)
        state.hasReturned = False
        return state, None
Exemple #3
0
    def pop(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        if len(regs) == 0:
            return state, None
        # head, *tail = registers

        address = state.getReg("SP")
        # check address is in 0...stacksize
        if address > (state.getLabelAddress("__STACKSIZE")) or address < 0:
            return state, programState.RunError("All stack entries have been pop'ed already", programState.RunError.ErrorType.Error)
        for reg in regs:
            err = state.loadRegister(address, 32, False, reg)
            address += 4
            if err is not None:
                return state, err
        state.setReg("SP", address)
        return state, None
Exemple #4
0
    def push(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        if len(regs) == 0:
            return state, None
        # head, *tail = registers

        address = state.getReg("SP")
        # check address is in 0...stacksize
        if address > (state.getLabelAddress("__STACKSIZE")) or address < 0:
            return state, programState.RunError("Stack overflow", programState.RunError.ErrorType.Error)

        for reg in regs:
            address -= 4
            err = state.storeRegister(address, reg, 32)
            if err is not None:
                return state, err
        state.setReg("SP", address)
        return state, None
Exemple #5
0
    def run(state: programState.ProgramState) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]:
        a = state.getReg(arg2)
        if isinstance(arg3, str):
            b = state.getReg(arg3)
            if b > 31:
                return state, programState.RunError(f"Shift value is out of range: value must be below 32 but is {b}", programState.RunError.ErrorType.Error)
        else:
            b = arg3

        out = a << b
        out32 = out & 0xFFFF_FFFF

        if b == 0:
            c = state.status.C  # The C flag is unaffected if the shift value is 0 - ARM docs
        else:
            c = bool((out >> 32) & 1)  # Get the last bit shifted out
        n = bool((out32 >> 31) & 1)
        z = out32 == 0

        state.setReg(arg1, out32)
        state.setALUState(programState.StatusRegister(n, z, c, False))

        return state, None