Skip to content

Commit b6370b3

Browse files
koachanandreas-gaisler
authored andcommitted
sparc/vdso: Add helper function for 64-bit right shift on 32-bit target
Add helper function for 64-bit right shift on 32-bit target so that clang does not emit a runtime library call. Signed-off-by: Koakuma <[email protected]> Reviewed-by: Andreas Larsson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andreas Larsson <[email protected]>
1 parent 8467d8b commit b6370b3

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

arch/sparc/vdso/vclock_gettime.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv,
8686
}
8787

8888
#ifdef CONFIG_SPARC64
89+
notrace static __always_inline u64 __shr64(u64 val, int amt)
90+
{
91+
return val >> amt;
92+
}
93+
8994
notrace static __always_inline u64 vread_tick(void)
9095
{
9196
u64 ret;
@@ -102,6 +107,21 @@ notrace static __always_inline u64 vread_tick_stick(void)
102107
return ret;
103108
}
104109
#else
110+
notrace static __always_inline u64 __shr64(u64 val, int amt)
111+
{
112+
u64 ret;
113+
114+
__asm__ __volatile__("sllx %H1, 32, %%g1\n\t"
115+
"srl %L1, 0, %L1\n\t"
116+
"or %%g1, %L1, %%g1\n\t"
117+
"srlx %%g1, %2, %L0\n\t"
118+
"srlx %L0, 32, %H0"
119+
: "=r" (ret)
120+
: "r" (val), "r" (amt)
121+
: "g1");
122+
return ret;
123+
}
124+
105125
notrace static __always_inline u64 vread_tick(void)
106126
{
107127
register unsigned long long ret asm("o4");
@@ -154,7 +174,7 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar,
154174
ts->tv_sec = vvar->wall_time_sec;
155175
ns = vvar->wall_time_snsec;
156176
ns += vgetsns(vvar);
157-
ns >>= vvar->clock.shift;
177+
ns = __shr64(ns, vvar->clock.shift);
158178
} while (unlikely(vvar_read_retry(vvar, seq)));
159179

160180
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
@@ -174,7 +194,7 @@ notrace static __always_inline int do_realtime_stick(struct vvar_data *vvar,
174194
ts->tv_sec = vvar->wall_time_sec;
175195
ns = vvar->wall_time_snsec;
176196
ns += vgetsns_stick(vvar);
177-
ns >>= vvar->clock.shift;
197+
ns = __shr64(ns, vvar->clock.shift);
178198
} while (unlikely(vvar_read_retry(vvar, seq)));
179199

180200
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
@@ -194,7 +214,7 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar,
194214
ts->tv_sec = vvar->monotonic_time_sec;
195215
ns = vvar->monotonic_time_snsec;
196216
ns += vgetsns(vvar);
197-
ns >>= vvar->clock.shift;
217+
ns = __shr64(ns, vvar->clock.shift);
198218
} while (unlikely(vvar_read_retry(vvar, seq)));
199219

200220
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
@@ -214,7 +234,7 @@ notrace static __always_inline int do_monotonic_stick(struct vvar_data *vvar,
214234
ts->tv_sec = vvar->monotonic_time_sec;
215235
ns = vvar->monotonic_time_snsec;
216236
ns += vgetsns_stick(vvar);
217-
ns >>= vvar->clock.shift;
237+
ns = __shr64(ns, vvar->clock.shift);
218238
} while (unlikely(vvar_read_retry(vvar, seq)));
219239

220240
ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);

0 commit comments

Comments
 (0)