Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Generate x86 Assembly with Go (github.com/mmcloughlin)
34 points by mmcloughlin on Jan 8, 2019 | hide | past | favorite | 2 comments



In the MIPS port of the Linux kernel, there is a module which assembles a handler for TLB faults, right into memory, each time the kernel boots up:

https://elixir.bootlin.com/linux/v4.20/source/arch/mips/mm/t...

the code is spread among various C functions. All the uasm_() and UASM_() calls assemble an instruction, e.g.:

  if (bcm1250_m3_war()) {
		unsigned int segbits = 44;

		uasm_i_dmfc0(&p, K0, C0_BADVADDR);
		uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
		uasm_i_xor(&p, K0, K0, K1);
		uasm_i_dsrl_safe(&p, K1, K0, 62);
		uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
		uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
		uasm_i_or(&p, K0, K0, K1);
		uasm_il_bnez(&p, &r, K0, label_leave);
		/* No need for uasm_i_nop */
The K0 and K1 refer to a pair of registers that, according to the MIPS architecture, TLB handlers can use without saving or restoring. These registers thus appear to have unstable values from the POV of the interrupted user or kernel space program.

I know about this module because I once patched it to make it preserve the value of the K0 register. The K0 register then appeared to have a stable value in user space, and I was able to patch glibc to use refer to that register for the thread_self() context value. This saved a trip to the kernel, making pthread_<everthing> faster: mutexes, conditions, you name it. I patched GCC's thread local storage mechanism to also use this.

When looking for the trap handler assembly code, I could not find it in any .S file; then I discovered it's being synthesized at run-time by C code.


k0, k1 are intended for use by any exception handler, not just TLB handlers.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: