writei: workaround for sdcc
authorAlan Cox <alan@linux.intel.com>
Sat, 10 Feb 2018 00:09:13 +0000 (00:09 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 10 Feb 2018 00:09:13 +0000 (00:09 +0000)
sdcc at least isn't bright enough to turn

static uint32 x

if (x >> 25)

into a byte load of x + 3 followed by an &0xFE

Instead it generates a 25 repeat bitshift of a 32bit value across four
registers in a fairly critical code path.

Allow defines to help it out with its dumbness.

Kernel/cpu-z80/cpu.h
Kernel/include/kernel.h
Kernel/inode.c

index 6279ea6..cb5583c 100644 (file)
@@ -84,3 +84,6 @@ typedef union {            /* this structure is endian dependent */
                          (((x) & 0xFF0000) >> 8) | (((x >> 24) & 0xFF)))
 
 #define CPUTYPE        CPUTYPE_Z80
+
+/* Deal with SDCC code gen issue */
+#define HIBYTE32(x)    (((uint8_t *)&(x))[3])
index e21aaeb..b0280ba 100644 (file)
@@ -40,6 +40,15 @@ From UZI by Doug Braun and UZI280 by Stefan Nitschke.
 #define ALIGNDOWN(v) (v)
 #endif
 
+/* These work fine for most compilers but can be overriden for those where the
+   resulting code generation is foul */
+#ifndef LOWORD
+#define LOWORD(x)      ((uint16_t)(x))
+#endif
+#ifndef HIBYTE32
+#define HIBYTE32(x)    ((uint8_t)((x) >> 24))
+#endif
+
 #ifdef CONFIG_LEVEL_2
 #include "level2.h"
 #else
@@ -152,7 +161,7 @@ typedef uint16_t blkno_t;    /* Can have 65536 512-byte blocks in filesystem */
 #define BLKSIZE                512
 #define BLKSHIFT       9
 #define BLKMASK                511
-#define BLKOVERSIZE    25      /* Bits 25+ mean we exceeded the file size */
+#define BLKOVERSIZE32  0xFE    /* Bits 25+ mean we exceeded the file size */
 
 /* Help the 8bit compilers out by preventing any 32bit promotions */
 #define BLKOFF(x)      (((uint16_t)(x)) & BLKMASK)
index 340c5db..8c8650f 100644 (file)
@@ -22,7 +22,7 @@ static uint8_t pipewait(inoptr ino, uint8_t flag)
                         return 0;
                 }
         }
-       udata.u_count = min(udata.u_count, (uint16_t)ino->c_node.i_size);
+       udata.u_count = min(udata.u_count, LOWORD(ino->c_node.i_size));
         return 1;
 }
 
@@ -127,7 +127,7 @@ void readi(regptr inoptr ino, uint8_t flag)
                         gcc_miscompile_workaround();
 #endif
                        umove(amount);
-                       if (ispipe && (uint16_t)udata.u_offset >= 18 * BLKSIZE)
+                       if (ispipe && LOWORD(udata.u_offset) >= 18 * BLKSIZE)
                                udata.u_offset = 0;
                        if (ispipe) {
                                ino->c_node.i_size -= amount;
@@ -177,7 +177,7 @@ void writei(regptr inoptr ino, uint8_t flag)
                /* FIXME: this will hang if you ever write > 16 * BLKSIZE
                   in one go - needs merging into the loop */
                while (udata.u_count > (16 * BLKSIZE) -
-                                       (uint16_t)ino->c_node.i_size) {
+                                       LOWORD(ino->c_node.i_size)) {
                        if (ino->c_readers == 0) {      /* No readers */
                                udata.u_done = (usize_t)-1;
                                udata.u_error = EPIPE;
@@ -198,7 +198,7 @@ void writei(regptr inoptr ino, uint8_t flag)
                while (udata.u_count) {
                        pblk = mapcalc(ino, &amount, 0);
 
-                        if (udata.u_offset >> BLKOVERSIZE) {
+                        if (HIBYTE32(udata.u_offset) & BLKOVERSIZE32) {
                                 udata.u_error = EFBIG;
                                 ssig(udata.u_ptab, SIGXFSZ);
                                 break;
@@ -222,7 +222,7 @@ void writei(regptr inoptr ino, uint8_t flag)
 
                        umove(amount);
                        if (ispipe) {
-                               if ((uint16_t)udata.u_offset >= 18 * 512)
+                               if (LOWORD(udata.u_offset) >= 18 * 512)
                                        udata.u_offset = 0;
                                ino->c_node.i_size += amount;
                                /* Wake up any readers */