this simplifies the asm in spllower. the trap that break forces to run reads the new cpl value out of arg0 (r26) and puts the old valud in r28 (ret0). the current asm is convoluted in how it gets the compiler to avoid those regs across the asm.
right now it has gcc place the ncpl value in ret0, and uses asm to copy that into arg0 before the break. it lists arg0 as a clobber so gcc will avoid it before running this code. it also marks ret0 as writable, which is correct. this moves to using two register asm variables, one each for arg0 and ret0, and only uses them as input and output operands respectively. this lets gcc place the ncpl value in the input register, which it does a good job of, and it avoids the extra copy operation. ive only used this as part of a bigger diff. im compiling a kernel with just it now, but it takes ages. 180MHz cpus arent as good as i remember them being. ok? Index: include/intr.h =================================================================== RCS file: /cvs/src/sys/arch/hppa/include/intr.h,v retrieving revision 1.42 diff -u -p -r1.42 intr.h --- include/intr.h 13 Sep 2015 14:58:20 -0000 1.42 +++ include/intr.h 17 May 2017 03:58:32 -0000 @@ -92,11 +92,15 @@ void intr_barrier(void *); static __inline int spllower(int ncpl) { - register int ocpl asm("r28") = ncpl; - __asm volatile("copy %0, %%arg0\n\tbreak %1, %2" - : "+r" (ocpl) : "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_SPLLOWER) - : "r26", "memory"); - return (ocpl); + register int arg0 asm("r26") = ncpl; + register int ret0 asm("r28"); + + __asm volatile("break %1, %2" + : "=r" (ret0) + : "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_SPLLOWER), "r" (arg0) + : "memory"); + + return (ret0); } static __inline int