This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UPREDICTABLE instructions

Any idea about instructions marked as UNPREDICTABLE: can it then be UNDEFINED?

In other words: UNDEFINED REQUIRES the instruction to cause UND-exception, but

MAY UNPREDICTABLE do that, or does it have to execute normally except that the result may be whatever?

(I'm not yelling even if I used caps.)

I did as that same thing there Re: ARM/THUMB instructions that change execution path?

but I don't seem to get any answers. And this is probably more appropriate space anyway.

  • Hi turboscrew,

    This is defined pretty well in the documentation. From the ARMv7-A/R ARM:

    Means the behavior cannot be relied upon. UNPREDICTABLE behavior must not perform any function that cannot be

    performed at the current or a lower level of privilege using instructions that are not UNPREDICTABLE.

    UNPREDICTABLE behavior must not be documented or promoted as having a defined effect.

    An instruction that is UNPREDICTABLE can be implemented as UNDEFINED.

    ...

    Therefore the simple answer to your question is.. yes. Treating any UNPREDICTABLE instruction as UNDEFINED is a perfectly valid treatment. However it leaves implementation options open to do something else like silently place garbage result data into a register or do nothing at all.

    As an example, in the ARMv8 Architecture, any attempt to execute any code from a region marked as Device memory is UNPREDICTABLE. It is possible that this would be some kind of exception and the kind of exception would be similarly UNPREDICTABLE - perhaps an ESR_ELx.EC reporting unknown reason, or permissions fault, or an execution abort, and optionally set the ILLEGAL flag in the PSTATE, or none of those.

    It does turn out, however, that the Cortex-A53 and Cortex-A57 execute code just fine from Device memory. The moral is that you cannot and should never rely on the fact that just because one core does a very particular thing, that all other cores (or any other cores) will follow suit. This is all there to be sure that code written to the architectural specifications will port across implementations. In the example (and pretty much any other example I can think of), it would be considered a software development problem (i.e. programmer error) to map instruction memory with the Device memory type and less than sympathetic support.

    Ta,

    Matt Sealey

  • My purpose was to figure out how to handle single stepping when UNPREDICTBLE instruction is encountered.

    I must treat it as UNDEFINED (refuse to step), or the code may run away.

    Thanks for the more detailed explanation.

  • Hi turboscrew,

    When most debuggers encounter an UNPREDICTABLE instruction during stepping.. they step into it. You wouldn't want to change the behaviour of the code any more than the debugger already does modify the state of the system.

    It would be extremely useful to warn a user that the next instruction has potentially UNPREDICTABLE behaviours (or is deprecated for some reason) but there's not a lot you can do.

    Ta,

    Matt

  • But if the UNPREDICTABLE happens to be UNDEFINED, it'll cause an exception in the middle of single step.

    Hmm...

    I was wrestling with myself with this...

  • You can't guarantee it'll be UNDEFINED - all you can do is present something to state that stepping into that instruction may have an UNPREDICTABLE effect.

    If you are writing a debug monitor then you have control over the Undef handler, surely? If it's external debug then you can use Vector Catch, if not then it's the debug monitor's responsibility (by design) to handle any exceptions caused by debug events. You should already have good reason to be hooked in to that handler otherwise you couldn't handle a breakpoint instruction..


  • I think, for now I'll settle with this:

    #ifdef INSTR_ALLOW_UNPREDS

    #define INSTR_ADDR_IMPL_DEP(x) (x )

    #else

    #define INSTR_ADDR_IMPL_DEP(x) INSTR_ADDR_UNPRED

    #endif

    Later I could change the new address into a flag-address pair.

    Then the main program gets the address, but also knows to inform the user about unpredictable step.

    I'm using BKPT and supervisor mode, so the debug exception should be PABT.

    As my first ARM-project, the debug mode (not to mention the debug co-processor) seems too complicated especially now that I don't have any hardware for debugging the target (bare metal, no jtag/j-link/st-link,...).

    That's why the previous weird questions. ;-)

  • Aha :)


    BKPT only exists ARMv5 and above so debuggers that attempt to support older architectures instead use a known unallocated encoding to trap instructions as Undef. If you're only concerned about newer cores then maybe you can get away with it - that said if you're arguing that you can handle an abort exception then handling Undef shouldn't be too big a pain.

  • There's a vector and banked regs set up already. The idea is to catch most exceptions.

    I'm writing it specifically to my Raspberry Pi 2B (but I hope it'll work on the other RPi-versions too).

    This is my private "blinky"-project, except that it doesn't blink a LED.

    (Isn't that usually the first ever program on new HW?)

    The SW I'm trying to put together is some kind of standalone gdb-stub (with included serial I/O).

    It should be able to load a program via the serial line and debug it.

    At the moment only single core is supported.