We do a lot of compares and switches with getmode and the switches in particular
get expensive on an 8 bit processor. Instead shift stuff and force it all into
8bit space.
This saves us a couple of hundred bytes even though SDCC still writes very
poor code for 8bit switches
Alan
}
i_deref(wd);
wd = ninode;
- if(getmode(wd) != F_DIR){
+ if(getmode(wd) != MODE_R(F_DIR)){
udata.u_error = ENOTDIR;
goto nodir;
}
int sh;
uint16_t dev;
- if(getmode(ip) == F_BDEV)
+ if(getmode(ip) == MODE_R(F_BDEV))
return(bn);
dev = ip->c_dev;
}
-uint16_t getmode(inoptr ino)
+uint8_t getmode(inoptr ino)
{
- return(ino->c_node.i_mode & F_MASK);
+ /* Shifting by 9 (past permissions might be more logical but
+ 8 happens to be cheap */
+ return (ino->c_node.i_mode & F_MASK) >> 8;
}
* syscall banks. */
arg_t unlinki(inoptr ino, inoptr pino, char *fname)
{
- if (getmode(ino) == F_DIR) {
+ if (getmode(ino) == MODE_R(F_DIR)) {
udata.u_error = EISDIR;
return -1;
}
#define F_MASK 0170000
+/* So we can do all our getmode comparisons in 8bit to help the compilers out */
+#define MODE_R(x) ((uint8_t)((x) >> 8))
+
#define major(x) ((x) >> 8)
#define minor(x) ((x) & 0xFF)
extern bool esuper(void);
extern uint8_t getperm(inoptr ino);
extern void setftime(inoptr ino, uint8_t flag);
-extern uint16_t getmode(inoptr ino);
+extern uint8_t getmode(inoptr ino);
extern struct mount *fs_tab_get(uint16_t dev);
/* returns true on failure, false on success */
extern bool fmount(uint16_t dev, inoptr ino, uint16_t flags);
dev = ino->c_dev;
ispipe = false;
switch (getmode(ino)) {
- case F_DIR:
- case F_REG:
+ case MODE_R(F_DIR):
+ case MODE_R(F_REG):
/* See if end of file will limit read */
if (ino->c_node.i_size <= udata.u_offset)
toread = udata.u_count;
goto loop;
- case F_SOCK:
+ case MODE_R(F_SOCK):
#ifdef CONFIG_NET
udata.u_count = sock_read(ino, flag);
break;
#endif
- case F_PIPE:
+ case MODE_R(F_PIPE):
ispipe = true;
while (ino->c_node.i_size == 0 && !(flag & O_NDELAY)) {
if (ino->c_refs == 1) /* No writers */
}
goto loop;
- case F_BDEV:
+ case MODE_R(F_BDEV):
toread = udata.u_count;
dev = *(ino->c_node.i_addr);
}
break;
- case F_CDEV:
+ case MODE_R(F_CDEV):
udata.u_count = cdread(ino->c_node.i_addr[0], flag);
if (udata.u_count != (usize_t)-1)
switch (getmode(ino)) {
- case F_BDEV:
+ case MODE_R(F_BDEV):
dev = *(ino->c_node.i_addr);
- case F_DIR:
- case F_REG:
+ case MODE_R(F_DIR):
+ case MODE_R(F_REG):
ispipe = false;
towrite = udata.u_count;
goto loop;
#ifdef CONFIG_NET
- case F_SOCK:
+ case MODE_R(F_SOCK):
udata.u_count = sock_write(ino, flag);
break;
#endif
- case F_PIPE:
+ case MODE_R(F_PIPE):
ispipe = true;
/* FIXME: this will hang if you ever write > 16 * BLKSIZE
in one go - needs merging into the loop */
}
break;
- case F_CDEV:
+ case MODE_R(F_CDEV):
udata.u_count = cdwrite(ino->c_node.i_addr[0], flag);
if (udata.u_count != -1)
if (of_tab[oftindex].o_refs == 1) {
if (isdevice(ino))
d_close((int) (ino->c_node.i_addr[0]));
- if (getmode(ino) == F_REG && O_ACCMODE(of_tab[oftindex].o_access))
+ if (getmode(ino) == MODE_R(F_REG) && O_ACCMODE(of_tab[oftindex].o_access))
flush_dev = ino->c_dev;
#ifdef CONFIG_NET
if (issocket(ino))
}
setftime(ino, is_read ? A_TIME : (A_TIME | M_TIME | C_TIME));
- if (getmode(ino) == F_REG && is_read == 0
+ if (getmode(ino) == MODE_R(F_REG) && is_read == 0
&& (oftp->o_access & O_APPEND))
oftp->o_ptr = ino->c_node.i_size;
/* Initialize u_offset from file pointer */
return -1;
switch (getmode(ino)) {
/* Device types that automatically report some ready states */
- case F_BDEV:
- case F_REG:
+ case MODE_R(F_BDEV):
+ case MODE_R(F_REG):
outr |= m;
- case F_DIR:
+ case MODE_R(F_DIR):
inr |= m;
break;
- case F_PIPE:
+ case MODE_R(F_PIPE):
n = pipesel_begin(ino, n);
goto setbits;
- case F_CDEV:
+ case MODE_R(F_CDEV):
/* If unsupported we report the device as read/write ready */
if (d_ioctl
(ino->c_node.i_addr[0],
if (sum & m) {
ino = getinode(i);
switch (getmode(ino)) {
- case F_CDEV:
+ case MODE_R(F_CDEV):
d_ioctl(ino->c_node.i_addr[0], SELECT_END,
NULL);
break;
- case F_PIPE:
+ case MODE_R(F_PIPE):
pipesel_end(ino);
}
}
static arg_t chdiroot_op(inoptr ino, inoptr * p)
{
- if (getmode(ino) != F_DIR) {
+ if (getmode(ino) != MODE_R(F_DIR)) {
udata.u_error = ENOTDIR;
i_deref(ino);
return (-1);
if (fd != -1) {
if ((inode = getinode(fd)) == NULLINODE)
return -1;
- if (getmode(inode) != F_REG) {
+ if (getmode(inode) != MODE_R(F_REG)) {
udata.u_error = EINVAL;
return -1;
}
goto cantopen;
}
if (w) {
- if (getmode(ino) == F_DIR ) {
+ if (getmode(ino) == MODE_R(F_DIR)) {
udata.u_error = EISDIR;
goto cantopen;
}
ino = *iptr;
}
- if (trunc && getmode(ino) == F_REG) {
+ if (trunc && getmode(ino) == MODE_R(F_REG)) {
if (f_trunc(ino))
goto idrop;
for (j = 0; j < OFTSIZE; ++j)
/*
* Sleep process if no writer or reader
*/
- if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1
+ if (getmode(ino) == MODE_R(F_PIPE) && of_tab[oftindex].o_refs == 1
&& !(flag & O_NDELAY))
psleep(ino);
if (!(ino = n_open(name1, NULLINOPTR)))
return (-1);
- if (getmode(ino) == F_DIR && esuper())
+ if (getmode(ino) == MODE_R(F_DIR) && esuper())
goto nogood;
if (ino->c_node.i_nlink == 0xFFFF) {
/* Fixme: check for rmdir of /. - ditto for unlink ? */
/* Not a directory */
- if (getmode(ino) != F_DIR) {
+ if (getmode(ino) != MODE_R(F_DIR)) {
udata.u_error = ENOTDIR;
goto nogood;
}
return (-1);
}
- if (getmode(sino) != F_BDEV) {
+ if (getmode(sino) != MODE_R(F_BDEV)) {
udata.u_error = ENOTBLK;
goto nogood;
}
- if (getmode(dino) != F_DIR) {
+ if (getmode(dino) != MODE_R(F_DIR)) {
udata.u_error = ENOTDIR;
goto nogood;
}
if (!(sino = n_open(spec, NULLINOPTR)))
return (-1);
- if (getmode(sino) != F_BDEV) {
+ if (getmode(sino) != MODE_R(F_BDEV)) {
udata.u_error = ENOTBLK;
goto nogood;
}