[PATCH] 3/6 i386 dt-inline-cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



i386 inline assembler cleanup.

This change encapsulates descriptor and task register management.  Also,
it is possible to improve assembler generation in two cases; savesegment
may store the value in a register instead of a memory location, which
allows GCC to optimize stack variables into registers, and MOV MEM, SEG
is always a 16-bit write to memory, making the casting in math-emu
unnecessary.

Diffs against: 2.6.13-rc4 + cpu-inline-cleanup

Signed-off-by: Zachary Amsden <[email protected]>
Index: linux-2.6.13/arch/i386/kernel/doublefault.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/doublefault.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/doublefault.c	2005-07-29 11:49:18.000000000 -0700
@@ -20,7 +20,7 @@
 	struct Xgt_desc_struct gdt_desc = {0, 0};
 	unsigned long gdt, tss;
 
-	__asm__ __volatile__("sgdt %0": "=m" (gdt_desc): :"memory");
+	store_gdt(&gdt_desc);
 	gdt = gdt_desc.address;
 
 	printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
Index: linux-2.6.13/arch/i386/kernel/efi.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/efi.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/efi.c	2005-07-29 11:49:18.000000000 -0700
@@ -104,8 +104,7 @@
 	local_flush_tlb();
 
 	cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
-	__asm__ __volatile__("lgdt %0":"=m"
-			    (*(struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0])));
+	load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
 }
 
 static void efi_call_phys_epilog(void)
@@ -114,7 +113,7 @@
 
 	cpu_gdt_descr[0].address =
 		(unsigned long) __va(cpu_gdt_descr[0].address);
-	__asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr));
+	load_gdt(&cpu_gdt_descr);
 	cr4 = read_cr4();
 
 	if (cr4 & X86_CR4_PSE) {
Index: linux-2.6.13/arch/i386/kernel/reboot.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/reboot.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/reboot.c	2005-07-29 11:49:18.000000000 -0700
@@ -13,6 +13,7 @@
 #include <linux/dmi.h>
 #include <asm/uaccess.h>
 #include <asm/apic.h>
+#include <asm/desc.h>
 #include "mach_reboot.h"
 #include <linux/reboot_fixups.h>
 
@@ -242,13 +243,13 @@
 
 	/* Set up the IDT for real mode. */
 
-	__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));
+	load_idt(&real_mode_idt);
 
 	/* Set up a GDT from which we can load segment descriptors for real
 	   mode.  The GDT is not used in real mode; it is just needed here to
 	   prepare the descriptors. */
 
-	__asm__ __volatile__ ("lgdt %0" : : "m" (real_mode_gdt));
+	load_gdt(&real_mode_gdt);
 
 	/* Load the data segment registers, and thus the descriptors ready for
 	   real mode.  The base address of each segment is 0x100, 16 times the
@@ -316,7 +317,7 @@
 	if (!reboot_thru_bios) {
 		if (efi_enabled) {
 			efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
-			__asm__ __volatile__("lidt %0": :"m" (no_idt));
+			load_idt(&no_idt);
 			__asm__ __volatile__("int3");
 		}
 		/* rebooting needs to touch the page at absolute addr 0 */
@@ -325,7 +326,7 @@
 			mach_reboot_fixups(); /* for board specific fixups */
 			mach_reboot();
 			/* That didn't work - force a triple fault.. */
-			__asm__ __volatile__("lidt %0": :"m" (no_idt));
+			load_idt(&no_idt);
 			__asm__ __volatile__("int3");
 		}
 	}
Index: linux-2.6.13/arch/i386/kernel/signal.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/signal.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/signal.c	2005-07-29 11:49:18.000000000 -0700
@@ -278,9 +278,9 @@
 	int tmp, err = 0;
 
 	tmp = 0;
-	__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
+	savesegment(gs, tmp);
 	err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
-	__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
+	savesegment(fs, tmp);
 	err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
 
 	err |= __put_user(regs->xes, (unsigned int __user *)&sc->es);
Index: linux-2.6.13/arch/i386/kernel/traps.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/traps.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/traps.c	2005-07-29 11:49:18.000000000 -0700
@@ -1006,7 +1006,7 @@
 	 * it uses the read-only mapped virtual address.
 	 */
 	idt_descr.address = fix_to_virt(FIX_F00F_IDT);
-	__asm__ __volatile__("lidt %0" : : "m" (idt_descr));
+	load_idt(&idt_descr);
 }
 #endif
 
Index: linux-2.6.13/arch/i386/kernel/vm86.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/vm86.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/vm86.c	2005-07-29 11:49:18.000000000 -0700
@@ -294,8 +294,8 @@
  */
 	info->regs32->eax = 0;
 	tsk->thread.saved_esp0 = tsk->thread.esp0;
-	asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs));
-	asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs));
+	savesegment(fs, tsk->thread.saved_fs);
+	savesegment(gs, tsk->thread.saved_gs);
 
 	tss = &per_cpu(init_tss, get_cpu());
 	tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
Index: linux-2.6.13/arch/i386/kernel/cpu/common.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/cpu/common.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/kernel/cpu/common.c	2005-07-29 11:49:18.000000000 -0700
@@ -613,8 +613,8 @@
 	memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
 		GDT_ENTRY_TLS_ENTRIES * 8);
 
-	__asm__ __volatile__("lgdt %0" : : "m" (cpu_gdt_descr[cpu]));
-	__asm__ __volatile__("lidt %0" : : "m" (idt_descr));
+	load_gdt(&cpu_gdt_descr[cpu]);
+	load_idt(&idt_descr);
 
 	/*
 	 * Delete NT
Index: linux-2.6.13/arch/i386/math-emu/get_address.c
===================================================================
--- linux-2.6.13.orig/arch/i386/math-emu/get_address.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/math-emu/get_address.c	2005-07-29 11:49:18.000000000 -0700
@@ -155,7 +155,6 @@
 { 
   struct desc_struct descriptor;
   unsigned long base_address, limit, address, seg_top;
-  unsigned short selector;
 
   segment--;
 
@@ -173,17 +172,11 @@
       /* fs and gs aren't used by the kernel, so they still have their
 	 user-space values. */
     case PREFIX_FS_-1:
-      /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
-	 in the assembler statement. */
-
-      __asm__("mov %%fs,%0":"=r" (selector));
-      addr->selector = selector;
+      /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
+      savesegment(fs, addr->selector);
       break;
     case PREFIX_GS_-1:
-      /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
-	 in the assembler statement. */
-      __asm__("mov %%gs,%0":"=r" (selector));
-      addr->selector = selector;
+      savesegment(gs, addr->selector);
       break;
     default:
       addr->selector = PM_REG_(segment);
Index: linux-2.6.13/arch/i386/power/cpu.c
===================================================================
--- linux-2.6.13.orig/arch/i386/power/cpu.c	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/arch/i386/power/cpu.c	2005-07-29 11:49:18.000000000 -0700
@@ -42,17 +42,17 @@
 	/*
 	 * descriptor tables
 	 */
-	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
-	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("str %0"  : "=m" (ctxt->tr));
+ 	store_gdt(&ctxt->gdt_limit);
+ 	store_idt(&ctxt->idt_limit);
+ 	store_tr(ctxt->tr);
 
 	/*
 	 * segment registers
 	 */
-	asm volatile ("movw %%es, %0" : "=m" (ctxt->es));
-	asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs));
-	asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs));
-	asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss));
+ 	savesegment(es, ctxt->es);
+ 	savesegment(fs, ctxt->fs);
+ 	savesegment(gs, ctxt->gs);
+ 	savesegment(ss, ctxt->ss);
 
 	/*
 	 * control registers 
@@ -118,16 +118,16 @@
 	 * now restore the descriptor tables to their proper values
 	 * ltr is done i fix_processor_context().
 	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+ 	load_gdt(&ctxt->gdt_limit);
+ 	load_idt(&ctxt->idt_limit);
 
 	/*
 	 * segment registers
 	 */
-	asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
-	asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs));
-	asm volatile ("movw %0, %%gs" :: "r" (ctxt->gs));
-	asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss));
+ 	loadsegment(es, ctxt->es);
+ 	loadsegment(fs, ctxt->fs);
+ 	loadsegment(gs, ctxt->gs);
+ 	loadsegment(ss, ctxt->ss);
 
 	/*
 	 * sysenter MSRs
Index: linux-2.6.13/include/asm-i386/system.h
===================================================================
--- linux-2.6.13.orig/include/asm-i386/system.h	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/include/asm-i386/system.h	2005-07-29 11:49:18.000000000 -0700
@@ -93,13 +93,13 @@
 		".align 4\n\t"			\
 		".long 1b,3b\n"			\
 		".previous"			\
-		: :"m" (value))
+		: :"rm" (value))
 
 /*
  * Save a segment register away
  */
 #define savesegment(seg, value) \
-	asm volatile("mov %%" #seg ",%0":"=m" (value))
+	asm volatile("mov %%" #seg ",%0":"=rm" (value))
 
 /*
  * Clear and set 'TS' bit respectively
Index: linux-2.6.13/include/asm-i386/desc.h
===================================================================
--- linux-2.6.13.orig/include/asm-i386/desc.h	2005-07-29 11:49:12.000000000 -0700
+++ linux-2.6.13/include/asm-i386/desc.h	2005-07-29 11:49:18.000000000 -0700
@@ -30,6 +30,16 @@
 #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
 #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
 
+#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr))
+#define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr))
+#define load_tr(tr) __asm__ __volatile("ltr %0"::"mr" (tr))
+#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"mr" (ldt))
+
+#define store_gdt(dtr) __asm__ ("sgdt %0":"=m" (*dtr))
+#define store_idt(dtr) __asm__ ("sidt %0":"=m" (*dtr))
+#define store_tr(tr) __asm__ ("str %0":"=mr" (tr))
+#define store_ldt(ldt) __asm__ ("sldt %0":"=mr" (ldt))
+
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux