summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2015-10-08 14:22:27 +0200
committerVineet Gupta <vgupta@synopsys.com>2015-10-17 14:18:23 +0200
commit9fabcc636bf57dcb9c6fc5b1f34861c548944fd4 (patch)
treea3924e140769864304736e3f8354e62761bf693c
parentARC: [arcompact] entry.S: Document preemption games for L2 intr (diff)
downloadlinux-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>
-rw-r--r--arch/arc/kernel/entry-compact.S18
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