Fixes for mmix-knuth-mmixware

Hans-Peter Nilsson hp@bitrange.com
Mon Feb 11 18:07:00 GMT 2002


Hi.  A few patches (attached) for:
- Framework bugs, needs _link and should define _times, not times (a bug
  in common with other targets, it seems).
- Trying to handle file append completely wrong (there's actually no
  support for it in the simulator).
- Missing __volatile__ on the value-returning asms for simulator calls
  made them disappear if the values weren't used.  Bad if you expect some
  side-effect from them. :-)

Can I please commit this?  (Else please consider doing it for me.)
Can I commit changes to the mmixware files in the future, without explicit
approval?

2002-02-12  Hans-Peter Nilsson  <hp@bitrange.com>

	* libc/sys/mmixware/link.c: New.
	* libc/sys/mmixware/sys/syscall.h (TRAP1i, I3f): Make asm
	volatile.
	* libc/sys/mmixware/times.c (_times): Renamed from times.
	* libc/sys/mmixware/open.c (_open): Attempt to handle O_APPEND
	properly by reading previous contents, not through BinaryReadWrite.
	* libc/sys/mmixware/Makefile.am (lib_a_SOURCES): Add link.c
	* libc/sys/mmixware/Makefile.in: Regenerate.

(Nag: don't forget to regenerate libc/sys/mmixware/Makefile.in. ;-)

brgds, H-P
-------------- next part --------------
*** /dev/null	Tue Jan  1 05:00:00 1980
--- libc/sys/mmixware/link.c	Mon Dec 31 04:20:30 2001
***************
*** 0 ****
--- 1,25 ----
+ /* link stub for MMIXware.
+ 
+    Copyright (C) 2002 Hans-Peter Nilsson
+ 
+    Permission to use, copy, modify, and distribute this software is
+    freely granted, provided that the above copyright notice, this notice
+    and the following disclaimer are preserved with no changes.
+ 
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE.  */
+ 
+ #include <_ansi.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include "sys/syscall.h"
+ #include <errno.h>
+ 
+ int
+ _link ()
+ {
+   errno = EMLINK;
+   return -1;
+ }
Index: libc/sys/mmixware/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/Makefile.am,v
retrieving revision 1.1
diff -p -c -r1.1 Makefile.am
*** libc/sys/mmixware/Makefile.am	2001/11/12 21:04:41	1.1
--- libc/sys/mmixware/Makefile.am	2002/02/12 01:39:58
*************** noinst_LIBRARIES = lib.a
*** 8,14 ****
  
  lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \
  	execv.c execve.c fork.c fstat.c getpid.c isatty.c \
! 	kill.c lseek.c open.c pipe.c read.c \
  	sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \
  	times.c gettime.c setjmp.S
  
--- 8,14 ----
  
  lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \
  	execv.c execve.c fork.c fstat.c getpid.c isatty.c \
! 	kill.c link.c lseek.c open.c pipe.c read.c \
  	sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \
  	times.c gettime.c setjmp.S
  
Index: libc/sys/mmixware/open.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/open.c,v
retrieving revision 1.3
diff -p -c -r1.3 open.c
*** libc/sys/mmixware/open.c	2001/11/18 23:47:59	1.3
--- libc/sys/mmixware/open.c	2002/02/12 01:39:58
***************
*** 1,6 ****
  /* open for MMIXware.
  
!    Copyright (C) 2001 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
  /* open for MMIXware.
  
!    Copyright (C) 2001, 2002 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
***************
*** 11,16 ****
--- 11,17 ----
     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE.  */
  
+ #include <stdlib.h>
  #include <fcntl.h>
  #include <_ansi.h>
  #include <sys/types.h>
*************** _open (const char *path,
*** 37,43 ****
  {
    long fileno;
    unsigned char mode;
!   long fffile = 0;
    long ret;
  
    for (fileno = 0;
--- 38,46 ----
  {
    long fileno;
    unsigned char mode;
!   long append_contents = 0;
!   unsigned long prev_contents_size = 0;
!   char *prev_contents = NULL;
    long ret;
  
    for (fileno = 0;
*************** _open (const char *path,
*** 55,61 ****
      }
  
    /* We map this to a fopen call.  The flags parameter is stymied because
!      we don't support more other than these flags.  */
    if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
      {
        UNIMPLEMENTED (("path: %s, flags: %d", path, flags));
--- 58,64 ----
      }
  
    /* We map this to a fopen call.  The flags parameter is stymied because
!      we don't support other than these flags.  */
    if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
      {
        UNIMPLEMENTED (("path: %s, flags: %d", path, flags));
*************** _open (const char *path,
*** 68,79 ****
    else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND))
      {
        mode = BinaryReadWrite;
!       fffile = 1;
      }
    else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND))
      {
        mode = BinaryReadWrite;
!       fffile = 1;
      }
    else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT)
  	   || (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC))
--- 71,82 ----
    else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND))
      {
        mode = BinaryReadWrite;
!       append_contents = 1;
      }
    else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND))
      {
        mode = BinaryReadWrite;
!       append_contents = 1;
      }
    else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT)
  	   || (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC))
*************** _open (const char *path,
*** 88,93 ****
--- 91,189 ----
        return -1;
      }
  
+   if (append_contents)
+     {
+       /* BinaryReadWrite is equal to "w+", so it truncates the file rather
+ 	 than keeping the contents, as can be imagined if you're looking
+ 	 for append functionality.  The only way we can keep the contents
+ 	 so we can append to it, is by first reading in and saving the
+ 	 contents, then re-opening the file as BinaryReadWrite and write
+ 	 the previous contents.  This seems to work for the needs of
+ 	 simple test-programs.  */
+       long openexist = TRAP3f (SYS_Fopen, fileno, path, BinaryRead);
+       if (openexist == 0)
+ 	{
+ 	  /* Yes, this file exists, now opened, so let's read it and keep
+              the contents.  Better have the memory around for this to
+              work.  */
+ 	  long seekval = TRAP2f (SYS_Fseek, fileno, -1);
+ 
+ 	  if (seekval == 0)
+ 	    {
+ 	      prev_contents_size = TRAP1f (SYS_Ftell, fileno);
+ 
+ 	      /* If the file has non-zero size, we have something to
+ 		 append to.  */
+ 	      if (prev_contents_size != 0)
+ 		{
+ 		  /* Start reading from the beginning.  Ignore the return
+ 		     value from this call: we'll notice if we can't read
+ 		     as much as we want.  */
+ 		  TRAP2f (SYS_Fseek, fileno, 0);
+ 
+ 		  prev_contents = malloc (prev_contents_size);
+ 		  if (prev_contents != 0)
+ 		    {
+ 		      /* I don't like the thought of trying to read the
+ 			 whole file all at once, disregarding the size,
+ 			 because the host system might not support that
+ 			 and we'd get funky errors.  Read in 32k at a
+ 			 time.  */
+ 		      char *ptr = prev_contents;
+ 		      unsigned long read_more = prev_contents_size;
+ 		      unsigned long chunk_size = 1 << 15;
+ 
+ 		      while (read_more >= chunk_size)
+ 			{
+ 			  long readval
+ 			    = TRAP3f (SYS_Fread, fileno, ptr, chunk_size);
+ 
+ 			  if (readval != 0)
+ 			    {
+ 			      free (prev_contents);
+ 			      TRAP1f (SYS_Fclose, fileno);
+ 			      errno = EIO;
+ 			      return -1;
+ 			    }
+ 			  read_more -= chunk_size;
+ 			  ptr += chunk_size;
+ 			}
+ 
+ 		      if (read_more != 0)
+ 			{
+ 			  long readval
+ 			    = TRAP3f (SYS_Fread, fileno, ptr, read_more);
+ 			  if (readval != 0)
+ 			    {
+ 			      free (prev_contents);
+ 			      TRAP1f (SYS_Fclose, fileno);
+ 			      errno = EIO;
+ 			      return -1;
+ 			    }
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      /* Malloc of area to copy to failed.  The glibc
+ 			 manpage says its open can return ENOMEM due to
+ 			 kernel memory failures, so let's do that too
+ 			 here.  */
+ 		      errno = ENOMEM;
+ 		      return -1;
+ 		    }
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      /* Seek failed.  Gotta be some I/O error.  */
+ 	      errno = EIO;
+ 	      return -1;
+ 	    }
+ 
+ 	  TRAP1f (SYS_Fclose, fileno);
+ 	}
+     }
+ 
    ret = TRAP3f (SYS_Fopen, fileno, path, mode);
    if (ret < 0)
      {
*************** _open (const char *path,
*** 97,108 ****
        return -1;
      }
  
!   _MMIX_allocated_filehandle[fileno] = 1;
! 
!   if (fffile)
      {
!       TRAP2f (SYS_Fseek, fileno, -1);
      }
  
    return fileno;
  }
--- 193,237 ----
        return -1;
      }
  
!   if (prev_contents_size != 0)
      {
!       /* Write out the previous contents, a chunk at a time.  Leave the
! 	 file pointer at the end of the file.  */
!       unsigned long write_more = prev_contents_size;
!       unsigned long chunk_size = 1 << 15;
!       char *ptr = prev_contents;
! 
!       while (write_more >= chunk_size)
! 	{
! 	  long writeval
! 	    = TRAP3f (SYS_Fwrite, fileno, ptr, chunk_size);
! 	  if (writeval != 0)
! 	    {
! 	      free (prev_contents);
! 	      TRAP1f (SYS_Fclose, fileno);
! 	      errno = EIO;
! 	      return -1;
! 	    }
! 	  write_more -= chunk_size;
! 	  ptr += chunk_size;
! 	}
!       if (write_more != 0)
! 	{
! 	  long writeval
! 	    = TRAP3f (SYS_Fwrite, fileno, ptr, write_more);
! 	  if (writeval != 0)
! 	    {
! 	      free (prev_contents);
! 	      TRAP1f (SYS_Fclose, fileno);
! 	      errno = EIO;
! 	      return -1;
! 	    }
! 	}
! 
!       free (prev_contents);
      }
+ 
+   _MMIX_allocated_filehandle[fileno] = 1;
  
    return fileno;
  }
Index: libc/sys/mmixware/times.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/times.c,v
retrieving revision 1.3
diff -p -c -r1.3 times.c
*** libc/sys/mmixware/times.c	2001/11/18 23:47:59	1.3
--- libc/sys/mmixware/times.c	2002/02/12 01:39:58
***************
*** 1,6 ****
  /* times stub for MMIXware.
  
!    Copyright (C) 2001 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
  /* times stub for MMIXware.
  
!    Copyright (C) 2001, 2002 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
***************
*** 18,24 ****
  #include "sys/times.h"
  
  clock_t
! times (struct tms *buffer)
  {
    memset (buffer, 0, sizeof (*buffer));
    return 0;
--- 18,24 ----
  #include "sys/times.h"
  
  clock_t
! _times (struct tms *buffer)
  {
    memset (buffer, 0, sizeof (*buffer));
    return 0;
Index: libc/sys/mmixware/sys/syscall.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/mmixware/sys/syscall.h,v
retrieving revision 1.2
diff -p -c -r1.2 syscall.h
*** libc/sys/mmixware/sys/syscall.h	2001/11/18 23:47:59	1.2
--- libc/sys/mmixware/sys/syscall.h	2002/02/12 01:39:58
***************
*** 1,6 ****
  /* syscall defines for MMIXware.
  
!    Copyright (C) 2001 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
--- 1,6 ----
  /* syscall defines for MMIXware.
  
!    Copyright (C) 2001, 2002 Hans-Peter Nilsson
  
     Permission to use, copy, modify, and distribute this software is
     freely granted, provided that the above copyright notice, this notice
*************** extern unsigned char _MMIX_allocated_fil
*** 46,67 ****
  #define TMPFNO 127
  
  /* Simulator call with one argument.  Also used for zero-argument calls;
!    pass a zero as ARG1.  */
! #define TRAP1i(FUN, ARG1)				\
!  ({ long ret_;						\
!     __asm__ ("TRAP 0,%1,%2\n\tSET %0,$255"		\
! 	     : "=r" (ret_) : "i" (FUN), "i" (ARG1)	\
! 	     : "memory");				\
!     ret_;						\
   })
  
  /* Helper macros to cope with the file-handle parameter to the simulator
!    being *constant*.  We support up to 32 simultaneously open files.  */
! #define I3f(FUN, ARG1, N, ARGS)					\
!  if (ARG1 == N)							\
!    __asm__ ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255"	\
! 	    : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS)	\
! 	    : "memory")
  
  /* Using if:s rather than switches to help GCC optimize the rest away.  */
  #define DO32(FUN, ARG1, ARGS)			\
--- 46,75 ----
  #define TMPFNO 127
  
  /* Simulator call with one argument.  Also used for zero-argument calls;
!    pass a zero as ARG1.  Make the asm volatile so we can safely ignore the
!    return-value and only get the benefit from the supposed side-effect
!    without the asm being optimized away.  */
! #define TRAP1i(FUN, ARG1)			\
!  ({ long ret_;					\
!     __asm__ __volatile__			\
!       ("TRAP 0,%1,%2\n\tSET %0,$255"		\
!        : "=r" (ret_) : "i" (FUN), "i" (ARG1)	\
!        : "memory");				\
!     ret_;					\
   })
  
  /* Helper macros to cope with the file-handle parameter to the simulator
!    being *constant*.  We support up to 32 simultaneously open files.  Make
!    the asm volatile so we can safely ignore the return-value and get the
!    benefit from the supposed side-effect without the asm being optimized
!    away.  */
! 
! #define I3f(FUN, ARG1, N, ARGS)				\
!  if (ARG1 == N)						\
!    __asm__ __volatile__					\
!      ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255"	\
!       : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS)	\
!       : "memory")
  
  /* Using if:s rather than switches to help GCC optimize the rest away.  */
  #define DO32(FUN, ARG1, ARGS)			\


More information about the Newlib mailing list