Commit cfca4b5a authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARC: entry: use gp to cache task pointer (vs. r25)



The motivation is eventual ABI considerations for ARCv3 but even without
it this change us worthwhile as diffstat reduces 100 net lines

r25 is a callee saved register, normally not saved by entry code in
pt_regs. However because of its usage in CONFIG_ARC_CURR_IN_REG it needs
to be. This in turn requires a whole bunch of special casing when we
need to access r25. Then there is distinction between user mode r25 vs.
kernel mode r25 - hence distinct SAVE_CALLEE_SAVED_{USER,KERNEL}

Instead use gp which is a scratch register and thus saved already in entry
code. This cleans things up significantly and much nocer on eyes:

 - SAVE_CALLEE_SAVED_{USER,KERNEL} are now exactly same
 - no special user_r25 slot in pt_reggs

Note that typical global asm registers are callee-saved (r25), but gp is
not callee-saved thus needs additional -ffixed-<reg> toggle

Signed-off-by: default avatarVineet Gupta <vgupta@kernel.org>
parent fad84e39
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -492,11 +492,11 @@ config ARC_KVADDR_SIZE
	  kernel-user gutter)

config ARC_CURR_IN_REG
	bool "Dedicate Register r25 for current_task pointer"
	bool "cache current task pointer in gp"
	default y
	help
	  This reserved Register R25 to point to Current Task in
	  kernel mode. This saves memory access for each such access
	  This reserves gp register to point to Current Task in
	  kernel mode eliding memory access for each access


config ARC_EMUL_UNALIGNED
+3 −3
Original line number Diff line number Diff line
@@ -28,14 +28,14 @@ cflags-y += $(tune-mcpu-def-y)
endif
endif


ifdef CONFIG_ARC_CURR_IN_REG
# For a global register definition, make sure it gets passed to every file
# We had a customer reported bug where some code built in kernel was NOT using
# any kernel headers, and missing the r25 global register
# any kernel headers, and missing the global register
# Can't do unconditionally because of recursive include issues
# due to <linux/thread_info.h>
LINUXINCLUDE	+=  -include $(srctree)/arch/arc/include/asm/current.h
cflags-y	+= -ffixed-gp
endif

cflags-y				+= -fsection-anchors
@@ -67,7 +67,7 @@ cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables $(cfi)
# small data is default for elf32 tool-chain. If not usable, disable it
# This also allows repurposing GP as scratch reg to gcc reg allocator
disable_small_data := y
cflags-$(disable_small_data)		+= -mno-sdata -fcall-used-gp
cflags-$(disable_small_data)		+= -mno-sdata

cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= -mbig-endian
ldflags-$(CONFIG_CPU_BIG_ENDIAN)	+= -EB
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@

#ifdef CONFIG_ARC_CURR_IN_REG

register struct task_struct *curr_arc asm("r25");
register struct task_struct *curr_arc asm("gp");
#define current (curr_arc)

#else
+6 −11
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
 *              |      orig_r0      |
 *              |      event/ECR    |
 *              |      bta          |
 *              |      user_r25     |
 *              |      gp           |
 *              |      fp           |
 *              |      sp           |
@@ -56,7 +55,7 @@
	;                 hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
	;   4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
	;
	; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair
	; (B) Manually saved some regs: r12,r30, sp,fp,gp, ACCL pair

#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
	; carve pt_regs on stack (case #3), PC/STAT32 already on stack
@@ -157,17 +156,17 @@

	st	r10, [sp, PT_sp]	; SP (pt_regs->sp)

#ifdef CONFIG_ARC_CURR_IN_REG
	st	r25, [sp, PT_user_r25]
	GET_CURR_TASK_ON_CPU	r25
#endif

#ifdef CONFIG_ARC_HAS_ACCL_REGS
	ST2	r58, r59, PT_r58
#endif

	/* clobbers r10, r11 registers pair */
	DSP_SAVE_REGFILE_IRQ

#ifdef CONFIG_ARC_CURR_IN_REG
	GET_CURR_TASK_ON_CPU	gp
#endif

.endm

/*------------------------------------------------------------------------*/
@@ -188,10 +187,6 @@
	sr	r10, [AUX_USER_SP]
1:

#ifdef CONFIG_ARC_CURR_IN_REG
	ld	r25, [sp, PT_user_r25]
#endif

	/* clobbers r10, r11 registers pair */
	DSP_RESTORE_REGFILE_IRQ

+11 −24
Original line number Diff line number Diff line
@@ -151,14 +151,6 @@
	/* ARC700 doesn't provide auto-stack switching */
	SWITCH_TO_KERNEL_STK

#ifdef CONFIG_ARC_CURR_IN_REG
	/* Treat r25 as scratch reg (save on stack) and load with "current" */
	PUSH    r25
	GET_CURR_TASK_ON_CPU   r25
#else
	sub     sp, sp, 4
#endif

	st.a	r0, [sp, -8]    /* orig_r0 needed for syscall (skip ECR slot) */
	sub	sp, sp, 4	/* skip pt_regs->sp, already saved above */

@@ -179,6 +171,11 @@

	lr	r10, [ecr]
	st      r10, [sp, PT_event]    /* EV_Trap expects r10 to have ECR */

#ifdef CONFIG_ARC_CURR_IN_REG
	/* gp already saved on stack: now load with "current" */
	GET_CURR_TASK_ON_CPU   gp
#endif
.endm

/*--------------------------------------------------------------
@@ -208,11 +205,8 @@
	POP	gp
	RESTORE_R12_TO_R0

#ifdef CONFIG_ARC_CURR_IN_REG
	ld	r25, [sp, 12]
#endif
	ld  sp, [sp] /* restore original sp */
	/* orig_r0, ECR, user_r25 skipped automatically */
	/* orig_r0, ECR skipped automatically */
.endm

/* Dummy ECR values for Interrupts */
@@ -229,13 +223,6 @@

	SWITCH_TO_KERNEL_STK

#ifdef CONFIG_ARC_CURR_IN_REG
	/* Treat r25 as scratch reg (save on stack) and load with "current" */
	PUSH    r25
	GET_CURR_TASK_ON_CPU   r25
#else
	sub     sp, sp, 4
#endif

	PUSH	0x003\LVL\()abcd    /* Dummy ECR */
	sub	sp, sp, 8	    /* skip orig_r0 (not needed)
@@ -255,6 +242,10 @@
	PUSHAX	lp_start
	PUSHAX	bta_l\LVL\()

#ifdef CONFIG_ARC_CURR_IN_REG
	/* gp already saved on stack: now load with "current" */
	GET_CURR_TASK_ON_CPU   gp
#endif
.endm

/*--------------------------------------------------------------
@@ -282,11 +273,7 @@
	POP	gp
	RESTORE_R12_TO_R0

#ifdef CONFIG_ARC_CURR_IN_REG
	ld	r25, [sp, 12]
#endif
	ld  sp, [sp] /* restore original sp */
	/* orig_r0, ECR, user_r25 skipped automatically */
	ld  sp, [sp] /* restore original sp; orig_r0, ECR skipped implicitly */
.endm

/* Get thread_info of "current" tsk */
Loading