LinuxDNA Atom Optimzed Patch by Luyi Cheng and C. Tyler McAdams Benchmark results can be found at www.linuxdna.com/benchmarks.pdf This is a 64bit patch with a great edge for multitasking. The flags can be easily changed to optimize for your specific cpu type. There are also various bug fixes including long standing issues with ICC compiled modules and gzip kernel compression now works also. This patch was tested with icc v. 11.1.059 and 11.1.064 on an Atom 330 64bit cpu on LFS w/ Glibc-2.11, GCC-4.50.20091119 & Binutils-2.20.51.20091120. For the latest patches please always visit the linuxdna.com mirror. Tech support can be accessed at the Tech Support link at: linuxdna.com This patch is released under the GPL 2.0 license and contains no proprietary code or parts. ===================================================================== diff -Nur linux-2.6.33-rc7/Makefile linux-dna-2.6.33-rc7/Makefile --- linux-2.6.33-rc7/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/Makefile 2010-02-11 09:09:13.059257765 +0800 @@ -225,9 +225,9 @@ else if [ -x /bin/bash ]; then echo /bin/bash; \ else echo sh; fi ; fi) -HOSTCC = gcc +HOSTCC = icc HOSTCXX = g++ -HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCFLAGS = -w -O3 -fomit-frame-pointer HOSTCXXFLAGS = -O2 # Decide whether to build built-in, modular, or both. @@ -312,7 +312,7 @@ AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)icc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm @@ -529,7 +529,7 @@ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os else -KBUILD_CFLAGS += -O2 +KBUILD_CFLAGS += -O3 -vec-report1 -w endif include $(srctree)/arch/$(SRCARCH)/Makefile diff -Nur linux-2.6.33-rc7/arch/x86/Makefile linux-dna-2.6.33-rc7/arch/x86/Makefile --- linux-2.6.33-rc7/arch/x86/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/Makefile 2010-02-11 10:46:08.924701196 +0800 @@ -48,6 +48,7 @@ KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 + KBUILD_CFLAGS += -ffreestanding # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) @@ -55,8 +56,7 @@ cflags-$(CONFIG_MCORE2) += \ $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) - cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \ - $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) + cflags-$(CONFIG_MATOM) += $(call cc-option,-xSSE3_ATOM) $(call cc-option,-ip) $(call cc-option,-fp-model fast=2) $(call cc-option,-unroll-aggressive) $(call cc-option,-vec-guard-write) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) KBUILD_CFLAGS += $(cflags-y) @@ -106,8 +106,6 @@ KBUILD_CFLAGS += -Wno-sign-compare # KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -# prevent gcc from generating any FP code by mistake -KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) diff -Nur linux-2.6.33-rc7/arch/x86/boot/Makefile linux-dna-2.6.33-rc7/arch/x86/boot/Makefile --- linux-2.6.33-rc7/arch/x86/boot/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/boot/Makefile 2010-02-11 09:28:27.733380653 +0800 @@ -1,3 +1,4 @@ +CC=gcc # # arch/x86/boot/Makefile # @@ -57,10 +58,9 @@ # How to compile the 16-bit code. Note we always compile for -march=i386, # that way we can complain to the user if the CPU is insufficient. -KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ +KBUILD_CFLAGS := $(LINUXINCLUDE) -Os -D_SETUP -D__KERNEL__ \ -DDISABLE_BRANCH_PROFILING \ - -Wall -Wstrict-prototypes \ - -march=i386 -mregparm=3 \ + -march=i386 -w -m32 -mregparm=3 \ -include $(srctree)/$(src)/code16gcc.h \ -fno-strict-aliasing -fomit-frame-pointer \ $(call cc-option, -ffreestanding) \ @@ -68,7 +68,6 @@ $(call cc-option, -fno-unit-at-a-time)) \ $(call cc-option, -fno-stack-protector) \ $(call cc-option, -mpreferred-stack-boundary=2) -KBUILD_CFLAGS += $(call cc-option, -m32) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ GCOV_PROFILE := n diff -Nur linux-2.6.33-rc7/arch/x86/boot/compressed/Makefile linux-dna-2.6.33-rc7/arch/x86/boot/compressed/Makefile --- linux-2.6.33-rc7/arch/x86/boot/compressed/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/boot/compressed/Makefile 2010-02-11 09:51:24.189099798 +0800 @@ -1,3 +1,4 @@ +CC=icc # # linux/arch/x86/boot/compressed/Makefile # @@ -6,7 +7,7 @@ targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o -KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 +KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O3 -no-vec KBUILD_CFLAGS += -fno-strict-aliasing -fPIC KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING cflags-$(CONFIG_X86_32) := -march=i386 diff -Nur linux-2.6.33-rc7/arch/x86/boot/compressed/misc.c linux-dna-2.6.33-rc7/arch/x86/boot/compressed/misc.c --- linux-2.6.33-rc7/arch/x86/boot/compressed/misc.c 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/boot/compressed/misc.c 2010-02-11 09:11:54.638255877 +0800 @@ -117,6 +117,7 @@ * gzip declarations */ #define STATIC static +#define HANDLE_ICC #undef memset #undef memcpy diff -Nur linux-2.6.33-rc7/arch/x86/include/asm/current.h linux-dna-2.6.33-rc7/arch/x86/include/asm/current.h --- linux-2.6.33-rc7/arch/x86/include/asm/current.h 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/include/asm/current.h 2010-02-11 09:09:13.062264128 +0800 @@ -11,7 +11,7 @@ static __always_inline struct task_struct *get_current(void) { - return percpu_read_stable(current_task); + return percpu_read(current_task); } #define current get_current() diff -Nur linux-2.6.33-rc7/arch/x86/include/asm/percpu.h linux-dna-2.6.33-rc7/arch/x86/include/asm/percpu.h --- linux-2.6.33-rc7/arch/x86/include/asm/percpu.h 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/include/asm/percpu.h 2010-02-11 09:09:13.063263729 +0800 @@ -49,7 +49,7 @@ #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x #define __my_cpu_offset percpu_read(this_cpu_off) #else -#define __percpu_arg(x) "%P" #x +#define __percpu_arg(x) "%" #x #endif /* @@ -104,48 +104,36 @@ } \ } while (0) -#define percpu_from_op(op, var, constraint) \ +#define percpu_from_op(op, var) \ ({ \ typeof(var) pfo_ret__; \ switch (sizeof(var)) { \ case 1: \ asm(op "b "__percpu_arg(1)",%0" \ : "=q" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 2: \ asm(op "w "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 4: \ asm(op "l "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 8: \ asm(op "q "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ default: __bad_percpu_size(); \ } \ pfo_ret__; \ }) -/* - * percpu_read() makes gcc load the percpu variable every time it is - * accessed while percpu_read_stable() allows the value to be cached. - * percpu_read_stable() is more efficient and can be used if its value - * is guaranteed to be valid across cpus. The current users include - * get_current() and get_thread_info() both of which are actually - * per-thread variables implemented as per-cpu variables and thus - * stable for the duration of the respective task. - */ -#define percpu_read(var) percpu_from_op("mov", per_cpu__##var, \ - "m" (per_cpu__##var)) -#define percpu_read_stable(var) percpu_from_op("mov", per_cpu__##var, \ - "p" (&per_cpu__##var)) +#define percpu_read(var) percpu_from_op("mov", per_cpu__##var) #define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) #define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) #define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) diff -Nur linux-2.6.33-rc7/arch/x86/include/asm/thread_info.h linux-dna-2.6.33-rc7/arch/x86/include/asm/thread_info.h --- linux-2.6.33-rc7/arch/x86/include/asm/thread_info.h 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/include/asm/thread_info.h 2010-02-11 09:09:13.064262929 +0800 @@ -215,7 +215,7 @@ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - ti = (void *)(percpu_read_stable(kernel_stack) + + ti = (void *)(percpu_read(kernel_stack) + KERNEL_STACK_OFFSET - THREAD_SIZE); return ti; } diff -Nur linux-2.6.33-rc7/arch/x86/kernel/acpi/realmode/Makefile linux-dna-2.6.33-rc7/arch/x86/kernel/acpi/realmode/Makefile --- linux-2.6.33-rc7/arch/x86/kernel/acpi/realmode/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/kernel/acpi/realmode/Makefile 2010-02-11 09:27:48.573380754 +0800 @@ -1,3 +1,4 @@ +CC=gcc # # arch/x86/kernel/acpi/realmode/Makefile # @@ -28,11 +29,10 @@ # How to compile the 16-bit code. Note we always compile for -march=i386, # that way we can complain to the user if the CPU is insufficient. # Compile with _SETUP since this is similar to the boot-time setup code. -KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \ +KBUILD_CFLAGS := $(LINUXINCLUDE) -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \ -I$(srctree)/$(bootsrc) \ $(cflags-y) \ - -Wall -Wstrict-prototypes \ - -march=i386 -mregparm=3 \ + -w -m32 -march=i386 -mregparm=3 \ -include $(srctree)/$(bootsrc)/code16gcc.h \ -fno-strict-aliasing -fomit-frame-pointer \ $(call cc-option, -ffreestanding) \ @@ -40,7 +40,6 @@ $(call cc-option, -fno-unit-at-a-time)) \ $(call cc-option, -fno-stack-protector) \ $(call cc-option, -mpreferred-stack-boundary=2) -KBUILD_CFLAGS += $(call cc-option, -m32) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ GCOV_PROFILE := n diff -Nur linux-2.6.33-rc7/arch/x86/kernel/apic/Makefile linux-dna-2.6.33-rc7/arch/x86/kernel/apic/Makefile --- linux-2.6.33-rc7/arch/x86/kernel/apic/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/kernel/apic/Makefile 2010-02-11 09:09:13.066263451 +0800 @@ -17,3 +17,5 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o obj-$(CONFIG_X86_ES7000) += es7000_32.o obj-$(CONFIG_X86_SUMMIT) += summit_32.o +CFLAGS_apic.o=-O1 +CFLAGS_io_apic.o=-O1 diff -Nur linux-2.6.33-rc7/arch/x86/kernel/apic/nmi.c linux-dna-2.6.33-rc7/arch/x86/kernel/apic/nmi.c --- linux-2.6.33-rc7/arch/x86/kernel/apic/nmi.c 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/kernel/apic/nmi.c 2010-02-11 09:09:13.067262772 +0800 @@ -361,7 +361,7 @@ */ static DEFINE_PER_CPU(unsigned, last_irq_sum); -static DEFINE_PER_CPU(long, alert_counter); +static DEFINE_PER_CPU(local_t, alert_counter); static DEFINE_PER_CPU(int, nmi_touch); void touch_nmi_watchdog(void) @@ -438,8 +438,8 @@ * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ - __this_cpu_inc(per_cpu_var(alert_counter)); - if (__this_cpu_read(per_cpu_var(alert_counter)) == 5 * nmi_hz) + local_inc(&__get_cpu_var(alert_counter)); + if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) /* * die_nmi will return ONLY if NOTIFY_STOP happens.. */ @@ -447,7 +447,7 @@ regs, panic_on_timeout); } else { __get_cpu_var(last_irq_sum) = sum; - __this_cpu_write(per_cpu_var(alert_counter), 0); + local_set(&__get_cpu_var(alert_counter), 0); } /* see if the nmi watchdog went off */ diff -Nur linux-2.6.33-rc7/arch/x86/kernel/cpu/common.c linux-dna-2.6.33-rc7/arch/x86/kernel/cpu/common.c --- linux-2.6.33-rc7/arch/x86/kernel/cpu/common.c 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/kernel/cpu/common.c 2010-02-11 09:09:13.068258013 +0800 @@ -93,12 +93,12 @@ * TLS descriptors are currently at a different place compared to i386. * Hopefully nobody expects them at a fixed place (Wine?) */ - [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), - [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), - [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), - [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff), - [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), - [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff), + [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, + [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, + [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, + [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, + [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, #else [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), diff -Nur linux-2.6.33-rc7/arch/x86/kernel/cpu/mtrr/Makefile linux-dna-2.6.33-rc7/arch/x86/kernel/cpu/mtrr/Makefile --- linux-2.6.33-rc7/arch/x86/kernel/cpu/mtrr/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/kernel/cpu/mtrr/Makefile 2010-02-11 09:09:13.069263494 +0800 @@ -1,3 +1,5 @@ obj-y := main.o if.o generic.o state.o cleanup.o obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o - +CFLAGS_main.o=-O1 +CFLAGS_cleanup.o=-O1 +CFLAGS_if.o=-O1 diff -Nur linux-2.6.33-rc7/arch/x86/mm/Makefile linux-dna-2.6.33-rc7/arch/x86/mm/Makefile --- linux-2.6.33-rc7/arch/x86/mm/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/arch/x86/mm/Makefile 2010-02-11 09:09:13.069263494 +0800 @@ -26,3 +26,4 @@ obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o obj-$(CONFIG_MEMTEST) += memtest.o +CFLAGS_ioremap.o=-O1 diff -Nur linux-2.6.33-rc7/drivers/acpi/acpica/Makefile linux-dna-2.6.33-rc7/drivers/acpi/acpica/Makefile --- linux-2.6.33-rc7/drivers/acpi/acpica/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/drivers/acpi/acpica/Makefile 2010-02-11 09:09:13.071264415 +0800 @@ -45,3 +45,4 @@ acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o +CFLAGS_REMOVE_tbutils.o=-ip diff -Nur linux-2.6.33-rc7/drivers/char/Makefile linux-dna-2.6.33-rc7/drivers/char/Makefile --- linux-2.6.33-rc7/drivers/char/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/drivers/char/Makefile 2010-02-11 09:09:13.072274416 +0800 @@ -135,3 +135,4 @@ rm $@.tmp endif +CFLAGS_vt.o=-O1 diff -Nur linux-2.6.33-rc7/drivers/char/agp/Makefile linux-dna-2.6.33-rc7/drivers/char/agp/Makefile --- linux-2.6.33-rc7/drivers/char/agp/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/drivers/char/agp/Makefile 2010-02-11 09:09:13.072274416 +0800 @@ -19,3 +19,4 @@ obj-$(CONFIG_AGP_SWORKS) += sworks-agp.o obj-$(CONFIG_AGP_UNINORTH) += uninorth-agp.o obj-$(CONFIG_AGP_VIA) += via-agp.o +CFLAGS_isoch.o=-O1 diff -Nur linux-2.6.33-rc7/drivers/video/console/Makefile linux-dna-2.6.33-rc7/drivers/video/console/Makefile --- linux-2.6.33-rc7/drivers/video/console/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/drivers/video/console/Makefile 2010-02-11 09:09:13.073508097 +0800 @@ -39,3 +39,6 @@ ifeq ($(CONFIG_USB_SISUSBVGA_CON),y) obj-$(CONFIG_USB_SISUSBVGA) += font.o endif +CFLAGS_fbcon.o=-O1 +CFLAGS_bitblit.o=-O1 +CFLAGS_softcursor.o=-O1 diff -Nur linux-2.6.33-rc7/fs/ext4/Makefile linux-dna-2.6.33-rc7/fs/ext4/Makefile --- linux-2.6.33-rc7/fs/ext4/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/fs/ext4/Makefile 2010-02-11 09:09:13.074266458 +0800 @@ -11,3 +11,4 @@ ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o +CFLAGS_hash.o=-O1 diff -Nur linux-2.6.33-rc7/kernel/Makefile linux-dna-2.6.33-rc7/kernel/Makefile --- linux-2.6.33-rc7/kernel/Makefile 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/kernel/Makefile 2010-02-11 09:09:13.074266458 +0800 @@ -131,3 +131,6 @@ targets += timeconst.h $(obj)/timeconst.h: $(src)/timeconst.pl FORCE $(call if_changed,timeconst) +CFLAGS_pid.o=-O1 +CFLAGS_groups.o=-O1 +CFLAGS_cgroup.o=-O1 diff -Nur linux-2.6.33-rc7/kernel/module.c linux-dna-2.6.33-rc7/kernel/module.c --- linux-2.6.33-rc7/kernel/module.c 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/kernel/module.c 2010-02-11 09:09:13.076507859 +0800 @@ -2029,6 +2029,8 @@ versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); + if (!sechdrs[pcpuindex].sh_size) + pcpuindex=0; /* Don't keep modinfo and version sections. */ sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; diff -Nur linux-2.6.33-rc7/lib/zlib_inflate/inflate.c linux-dna-2.6.33-rc7/lib/zlib_inflate/inflate.c --- linux-2.6.33-rc7/lib/zlib_inflate/inflate.c 2010-02-07 06:17:12.000000000 +0800 +++ linux-dna-2.6.33-rc7/lib/zlib_inflate/inflate.c 2010-02-11 09:14:10.475257959 +0800 @@ -363,6 +363,120 @@ ret = Z_OK; for (;;) switch (state->mode) { +#ifdef HANDLE_ICC + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + state->mode = TABLE; + DROPBITS(2); + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); + state->have = 0; + state->mode = LENLENS; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const *)(state->next); + state->lenbits = 7; + ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + state->have = 0; + state->mode = CODELENS; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const *)(state->next); + state->lenbits = 9; + ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + state->distcode = (code const *)(state->next); + state->distbits = 6; + ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + state->mode = LEN; + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + INITBITS(); + } + state->mode = DONE; + ret = Z_STREAM_END; + goto inf_leave; + default: + return Z_STREAM_ERROR; + } +#else case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; @@ -721,6 +835,7 @@ default: return Z_STREAM_ERROR; } +#endif /* Return from inflate(), updating the total counts and the check value.