aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/gate.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/gate.S')
-rw-r--r--arch/ia64/kernel/gate.S62
1 files changed, 33 insertions, 29 deletions
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index facf75acdc85..86948ce63e43 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
72 * bundle get executed. The remaining code must be safe even if 72 * bundle get executed. The remaining code must be safe even if
73 * they do not get executed. 73 * they do not get executed.
74 */ 74 */
75 adds r17=-1024,r15 75 adds r17=-1024,r15 // A
76 mov r10=0 // default to successful syscall execution 76 mov r10=0 // A default to successful syscall execution
77 epc 77 epc // B causes split-issue
78} 78}
79 ;; 79 ;;
80 rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" 80 rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
81 LOAD_FSYSCALL_TABLE(r14) 81 LOAD_FSYSCALL_TABLE(r14) // X
82
83 mov r16=IA64_KR(CURRENT) // 12 cycle read latency
84 tnat.nz p10,p9=r15
85 mov r19=NR_syscalls-1
86 ;; 82 ;;
87 shladd r18=r17,3,r14 83 mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
88 84 shladd r18=r17,3,r14 // A
89 srlz.d 85 mov r19=NR_syscalls-1 // A
90 cmp.ne p8,p0=r0,r0 // p8 <- FALSE 86 ;;
91 /* Note: if r17 is a NaT, p6 will be set to zero. */ 87 lfetch [r18] // M0|1
92 cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? 88 mov r29=psr // M2 (12 cyc)
93 ;; 89 // If r17 is a NaT, p6 will be zero
94(p6) ld8 r18=[r18] 90 cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
95 mov r21=ar.fpsr 91 ;;
96 add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry 92 mov r21=ar.fpsr // M2 (12 cyc)
97 ;; 93 tnat.nz p10,p9=r15 // I0
98(p6) mov b7=r18 94 mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
99(p6) tbit.z p8,p0=r18,0 95 ;;
100(p8) br.dptk.many b7 96 srlz.d // M0 (forces split-issue) ensure PSR.BE==0
101 97(p6) ld8 r18=[r18] // M0|1
102(p6) rsm psr.i 98 nop.i 0
103 mov r27=ar.rsc 99 ;;
104 mov r26=ar.pfs 100 nop.m 0
101(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
102 nop.i 0
105 ;; 103 ;;
106 mov r29=psr // read psr (12 cyc load latency) 104(p8) ssm psr.i
105(p6) mov b7=r18 // I0
106(p8) br.dptk.many b7 // B
107
108 mov r27=ar.rsc // M2 (12 cyc)
107/* 109/*
108 * brl.cond doesn't work as intended because the linker would convert this branch 110 * brl.cond doesn't work as intended because the linker would convert this branch
109 * into a branch to a PLT. Perhaps there will be a way to avoid this with some 111 * into a branch to a PLT. Perhaps there will be a way to avoid this with some
@@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
111 * instead. 113 * instead.
112 */ 114 */
113#ifdef CONFIG_ITANIUM 115#ifdef CONFIG_ITANIUM
116(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
117 ;;
114(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down 118(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
115 ;; 119 ;;
116(p6) mov b7=r14 120(p6) mov b7=r14
@@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
118#else 122#else
119 BRL_COND_FSYS_BUBBLE_DOWN(p6) 123 BRL_COND_FSYS_BUBBLE_DOWN(p6)
120#endif 124#endif
121 125 ssm psr.i
122 mov r10=-1 126 mov r10=-1
123(p10) mov r8=EINVAL 127(p10) mov r8=EINVAL
124(p9) mov r8=ENOSYS 128(p9) mov r8=ENOSYS