Dedup a lot of code shared between x86 and x86_64
This makes it significantly easier to keep everything in sync. In fact I found a couple of minor places where x86 and x86_64 diverged, like missing the profiler IPI or the x86 port using the physical address of the local and IO APIC as the logical address even though they are likely different. I haven't deduplicated some of the files where the divergence was too big like the interrupt handlers.