Commit 72fbfb26 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

[MIPS] Fix optimization for size build.


    
It took a while longer than on other architectures but gcc has finally
started to strike us as well ...
    
This also fixes the damage by 6edfba1b.
    
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent aac076f8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ cflags-y += -msoft-float
LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
MODFLAGS			+= -mlong-calls

cflags-y += -ffreestanding

#
# We explicitly add the endianness specifier if needed, this allows
# to compile kernels with a toolchain for the other endianness. We
+3 −0
Original line number Diff line number Diff line
@@ -7,4 +7,7 @@ lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \

obj-y	+= iomap.o

# libgcc-style stuff needed in the kernel
lib-y += ashldi3.o ashrdi3.o lshrdi3.o

EXTRA_AFLAGS := $(CFLAGS)
+29 −0
Original line number Diff line number Diff line
#include <linux/module.h>

#include "libgcc.h"

long long __ashldi3(long long u, word_type b)
{
	DWunion uu, w;
	word_type bm;

	if (b == 0)
		return u;

	uu.ll = u;
	bm = 32 - b;

	if (bm <= 0) {
		w.s.low = 0;
		w.s.high = (unsigned int) uu.s.low << -bm;
	} else {
		const unsigned int carries = (unsigned int) uu.s.low >> bm;

		w.s.low = (unsigned int) uu.s.low << b;
		w.s.high = ((unsigned int) uu.s.high << b) | carries;
	}

	return w.ll;
}

EXPORT_SYMBOL(__ashldi3);
+31 −0
Original line number Diff line number Diff line
#include <linux/module.h>

#include "libgcc.h"

long long __ashrdi3(long long u, word_type b)
{
	DWunion uu, w;
	word_type bm;

	if (b == 0)
		return u;

	uu.ll = u;
	bm = 32 - b;

	if (bm <= 0) {
		/* w.s.high = 1..1 or 0..0 */
		w.s.high =
		    uu.s.high >> 31;
		w.s.low = uu.s.high >> -bm;
	} else {
		const unsigned int carries = (unsigned int) uu.s.high << bm;

		w.s.high = uu.s.high >> b;
		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
	}

	return w.ll;
}

EXPORT_SYMBOL(__ashrdi3);

arch/mips/lib/libgcc.h

0 → 100644
+26 −0
Original line number Diff line number Diff line
#ifndef __ASM_LIBGCC_H
#define __ASM_LIBGCC_H

#include <asm/byteorder.h>

typedef int word_type __attribute__ ((mode (__word__)));

#ifdef __BIG_ENDIAN
struct DWstruct {
	int high, low;
};
#elif defined(__LITTLE_ENDIAN)
struct DWstruct {
	int low, high;
};
#else
#error I feel sick.
#endif

typedef union
{
	struct DWstruct s;
	long long ll;
} DWunion;

#endif /* __ASM_LIBGCC_H */
Loading