diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-10-08 14:22:27 +0200 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-10-17 14:18:23 +0200 |
commit | 9fabcc636bf57dcb9c6fc5b1f34861c548944fd4 (patch) | |
tree | a3924e140769864304736e3f8354e62761bf693c /arch/arc | |
parent | ARC: [arcompact] entry.S: Document preemption games for L2 intr (diff) | |
download | linux-9fabcc636bf57dcb9c6fc5b1f34861c548944fd4.tar.xz linux-9fabcc636bf57dcb9c6fc5b1f34861c548944fd4.zip |
ARC: [arcompact] entry.S: Elide extra check/branch in exception ret path
This is done by improving the laddering logic !
Before:
if Exception
goto excep_or_pure_k_ret
if !Interrupt(L2)
goto l1_chk
else
INTERRUPT_EPILOGUE 2
l1_chk:
if !Interrupt(L1) (i.e. pure kernel mode)
goto excep_or_pure_k_ret
else
INTERRUPT_EPILOGUE 1
excep_or_pure_k_ret:
EXCEPTION_EPILOGUE
Now:
if !Interrupt(L1 or L2) (i.e. exception or pure kernel mode)
goto excep_or_pure_k_ret
; guaranteed to be an interrupt
if !Interrupt(L2)
goto l1_ret
else
INTERRUPT_EPILOGUE 2
; by virtue of above, no need to chk for L1 active
l1_ret:
INTERRUPT_EPILOGUE 1
excep_or_pure_k_ret:
EXCEPTION_EPILOGUE
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/kernel/entry-compact.S | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index d9087a1236eb..5221f194602b 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -333,11 +333,10 @@ END(call_do_page_fault) ; Note that we use realtime STATUS32 (not pt_regs->status32) to ; decide that. - ; if Returning from Exception - btst r10, STATUS_AE_BIT - bnz .Lexcep_ret + and.f 0, r10, (STATUS_A1_MASK|STATUS_A2_MASK) + bz .Lexcep_or_pure_K_ret - ; Not Exception so maybe Interrupts (Level 1 or 2) + ; Returning from Interrupts (Level 1 or 2) #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS @@ -378,8 +377,7 @@ END(call_do_page_fault) st r9, [r10, THREAD_INFO_PREEMPT_COUNT] 149: - ;return from level 2 - INTERRUPT_EPILOGUE 2 + INTERRUPT_EPILOGUE 2 ; return from level 2 interrupt debug_marker_l2: rtie @@ -387,15 +385,11 @@ not_level2_interrupt: #endif - bbit0 r10, STATUS_A1_BIT, .Lpure_k_mode_ret - - ;return from level 1 - INTERRUPT_EPILOGUE 1 + INTERRUPT_EPILOGUE 1 ; return from level 1 interrupt debug_marker_l1: rtie -.Lexcep_ret: -.Lpure_k_mode_ret: +.Lexcep_or_pure_K_ret: ;this case is for syscalls or Exceptions or pure kernel mode |