The Alpha AXP, part 11: Processor faults

Raymond Chen

There are three types of faults on the Alpha AXP:

  • Software faults
  • Hardware faults
  • Arithmetic faults

Software faults are those triggered by explicit instructions, such as CALL_PAL. These are calls that trap into the kernel and are used as the Alpha AXP version of syscall. Software faults are raised synchronously, and execution does not proceed past a software fault. Consequently, they are restartable.

Hardware faults are those triggered by things like page faults, hardware interrupts, or software emulation. Hardware faults are not necessarily raised synchronously; execution can proceed past a hardware fault before the fault is generated, but the fault is nevertheless restartable. Even though instructions past the faulting instruction may have already executed, they can safely be executed again.

Arithmetic faults are tricky.

The ADDx, SUBx and MULx instructions can take a /V suffix to indicate that the instruction should raise a processor trap if a signed integer overflow occurs.¹ There is a similar suffix that can be applied to floating point operations to trigger an arithmetic fault if something goes wrong in the floating point calculation.

The catch is that the trap is not required to be raised at the point of the operation. The processor is permitted to delay the overflow trap indefinitely, or until you do this:

    TRAPB

The trap barrier instruction tells the processor to raise any overflow traps that are still pending. The previous arithmetic operations need not run to completion; they only need to run far enough to confirm that no overflow has occurred. The processor is allowed to execute past the TRAPB instruction, as long as it can do so without violating the constraints of the TRAPB instruction.

In practice, you don’t see the /V suffix because C-like programming languages don’t raise overflow exceptions. They just define integer overflows to wrap, or leave the behavior undefined.

You usually see TRAPB instructions at the start and end of a function, and whenever code enters or exits a __try block. Basically, it happens any time there is a change to how exceptions are dispatched and unwound.

The fact that overflow traps can occur long after the operation that caused the overflow means that overflow traps are in general not recoverable, because you don’t know which register contains the overflowed value. (Indeed, the overflowed value may not even be in a register any more.) If you want your overflow traps to be recoverable, you need to put the TRAPB immediately after the instruction that potentially creates the overflow condition.

Okay, so that’s overflow. But what about carry? We’ll look at that next time.

¹ The presence of overflow detection means that the L versions of the instructions are not quite the same as “Perform the Q operation, and then sign-extend the low-order 32 bits of the result.” The numeric result is the same, but the overflow conditions are different.

0 comments

Discussion is closed.

Feedback usabilla icon