ipl: Avoid usage of 64-bit __udivdi3 millicode routine in ext2 code

Avoid using millicode routines in the ext2 code by using a simplified
bit-shifting mechanism to avoid u64 integer divisions.

Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/ipl/ext2.c b/ipl/ext2.c
index a468790..d05ec6c 100644
--- a/ipl/ext2.c
+++ b/ipl/ext2.c
@@ -64,6 +64,27 @@
 #undef DEBUG
 #define Debug 0
 
+/* div_blocksize() and mul_blocksize() are trivial functions to avoid 64-bit
+   __udivdi3 and __muldi3 millicode routines. They only work because the ext2
+   blocksize is a multiple of 2 */
+static __u64 div_blocksize(__u64 devaddr, unsigned blocksize)
+{
+	while (blocksize > 1) {
+		devaddr >>= 1;
+		blocksize >>= 1;
+	}
+	return devaddr;
+}
+static __u64 mul_blocksize(__u64 devaddr, unsigned blocksize)
+{
+	while (blocksize > 1) {
+		devaddr <<= 1;
+		blocksize >>= 1;
+	}
+	return devaddr;
+}
+
+
 static struct ext3_extent_header *ext3_extent_header(struct ext2_inode *i)
 {
 	return (struct ext3_extent_header *)&i->i_block[0];
@@ -363,7 +384,7 @@
 	printf("group is %d\n", group);
 #endif
 	offset = partition_offset
-		+ ((__u64) ext2_gds(group)->bg_inode_table * ext2_blocksize)
+		+ mul_blocksize(ext2_gds(group)->bg_inode_table, ext2_blocksize)
 		+ (((ino - 1) % EXT2_INODES_PER_GROUP(&sb))
 		   * EXT2_INODE_SIZE(&sb));
 #ifdef DEBUG
@@ -583,7 +604,7 @@
 
 		/* Read the indirect block */
 		if (cached_iblkno != iblkno) {
-			offset = partition_offset + (__u64)iblkno * ext2_blocksize;
+			offset = partition_offset + mul_blocksize(iblkno, ext2_blocksize);
 			if (cons_read(dev, iblkbuf, ext2_blocksize, offset)
 			    != ext2_blocksize)
 			{
@@ -610,7 +631,7 @@
 
 		/* Read in the double-indirect block */
 		if (cached_diblkno != diblkno) {
-			offset = partition_offset + (__u64) diblkno * ext2_blocksize;
+			offset = partition_offset + mul_blocksize(diblkno, ext2_blocksize);
 			if (cons_read(dev, diblkbuf, ext2_blocksize, offset)
 			    != ext2_blocksize)
 			{
@@ -631,7 +652,7 @@
 		/* Read the indirect block */
     
 		if (cached_iblkno != iblkno) {
-			offset = partition_offset + (__u64) iblkno * ext2_blocksize;
+			offset = partition_offset + mul_blocksize(iblkno, ext2_blocksize);
 			if (cons_read(dev, iblkbuf, ext2_blocksize, offset)
 			    != ext2_blocksize)
 			{
@@ -699,7 +720,7 @@
 			memset(buffer, 0, nbytes);
 		} else {
 			/* Read it for real */
-			offset = partition_offset + (__u64) dev_blkno * ext2_blocksize;
+			offset = partition_offset + mul_blocksize(dev_blkno, ext2_blocksize);
 #ifdef DEBUG
 			printf("ext2_bread: reading %ld bytes at offset %lld\n",
 			       nbytes, offset);
@@ -970,7 +991,7 @@
 		fd, buf, count, devaddr);
 
 	return ext2_breadi(ip,
-		devaddr / ext2_blocksize,
+		div_blocksize(devaddr, ext2_blocksize),
 		count / ext2_blocksize,
 		buf);
 }