Skip to content

Commit

Permalink
[MIPS] Fix optimization for size build.
Browse files Browse the repository at this point in the history
    
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 6edfba1.
    
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Ralf Baechle committed Jun 19, 2006
1 parent aac076f commit 72fbfb2
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 0 deletions.
2 changes: 2 additions & 0 deletions arch/mips/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions arch/mips/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 29 additions & 0 deletions arch/mips/lib/ashldi3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#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 changes: 31 additions & 0 deletions arch/mips/lib/ashrdi3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#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);
26 changes: 26 additions & 0 deletions arch/mips/lib/libgcc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#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 */
29 changes: 29 additions & 0 deletions arch/mips/lib/lshrdi3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <linux/module.h>

#include "libgcc.h"

long long __lshrdi3(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 = 0;
w.s.low = (unsigned int) uu.s.high >> -bm;
} else {
const unsigned int carries = (unsigned int) uu.s.high << bm;

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

return w.ll;
}

EXPORT_SYMBOL(__lshrdi3);

0 comments on commit 72fbfb2

Please sign in to comment.