* SP points to a minimal amount of processor-private memory, the address
  * of which is copied into r0 for the mode specific abort handler.
  */
-       .macro  vector_stub, name, correction=0
+       .macro  vector_stub, name, mode, correction=0
        .align  5
 
 vector_\name:
        @ Prepare for SVC32 mode.  IRQs remain disabled.
        @
        mrs     r0, cpsr
-       bic     r0, r0, #MODE_MASK
-       orr     r0, r0, #SVC_MODE
+       eor     r0, r0, #(\mode ^ SVC_MODE)
        msr     spsr_cxsf, r0
 
        @
        @ the branch table must immediately follow this code
        @
-       mov     r0, sp
        and     lr, lr, #0x0f
+       mov     r0, sp
        ldr     lr, [pc, lr, lsl #2]
        movs    pc, lr                  @ branch to handler in SVC mode
        .endm
 /*
  * Interrupt dispatcher
  */
-       vector_stub     irq, 4
+       vector_stub     irq, IRQ_MODE, 4
 
        .long   __irq_usr                       @  0  (USR_26 / USR_32)
        .long   __irq_invalid                   @  1  (FIQ_26 / FIQ_32)
  * Data abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-       vector_stub     dabt, 8
+       vector_stub     dabt, ABT_MODE, 8
 
        .long   __dabt_usr                      @  0  (USR_26 / USR_32)
        .long   __dabt_invalid                  @  1  (FIQ_26 / FIQ_32)
  * Prefetch abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-       vector_stub     pabt, 4
+       vector_stub     pabt, ABT_MODE, 4
 
        .long   __pabt_usr                      @  0 (USR_26 / USR_32)
        .long   __pabt_invalid                  @  1 (FIQ_26 / FIQ_32)
  * Undef instr entry dispatcher
  * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
-       vector_stub     und
+       vector_stub     und, UND_MODE
 
        .long   __und_usr                       @  0 (USR_26 / USR_32)
        .long   __und_invalid                   @  1 (FIQ_26 / FIQ_32)