Alpha (yet again, but it works now [?])

Dirk Grunwald grunwald at pa.dec.com
Thu Oct 22 18:24:17 PDT 1998


Godmar was right, I wasn't setting up the FP arguments correctly. I
think the following version does this correctly, but am not 100%
certain. I can pass all the regression tests other than GCTest,
including the TestNative case --- actually, a modified version of
TestNative that I am including in this SHAR as well.

Perhaps someone else can help with the following remaining
question(s):

1) This concerns the argument copy in the Alpha. Floats are 32 bits,
   doubles are 64. Little endian machine. For memory arguments, the
   calling convention just allocates 64 bits for each argument in
   memory. For arguments headed to registers, I copy the memory argument
   to both the integer and FP registers (cache-hitting loads are
   cheaper than branches). 32-bit ints are sign-extended to 64 bit.
   Floats are converted to doubles.

   I do the same thing for the memory loads *except* that I
   don't distinguish between integer and floating point values,
   since I'm really doing a "size-based" copy. This seems to
   work fine, since the compiler will load only the portion of
   the float/int that hasn't been changed/sign-extended.
   Anyone see why it shouldn't?

2) GCTest fails occasionally. 
	[rushmore] ./Kaffe GCTest
	[22]:  Failure: testObjArray: wanted 4
	[21]:  Failure: testObjChain at 85(0x1079229360): id is 85 (should be 85); name is 16 (should be '85').

   .. etc. Usually, it will run and just work, but these occasional
   flaws bother me. Anyone have any suggestions on how to debug? Are
   there module tests for the GC? Was it designed to work on 64-bit
   systems?

3) When I run the "WidgetsDemo", the JPG at the bottom doesn't
   display the transvirtual banner. All the other images work fine.
   Any clues?

4) I've started working on the JIT. What is the most complete RISC-like
   architecture that has JIT support? I'm assuming this is the Sparc.

5) There are a lot of alpha-related bits with the word "jit" in them, but
   based on the experience of getting the interpreter running, I don't know
   how much to trust them. Who did the Alpha port and what was the state
   when it was last used? Was only the JIT being used?

Here's
	+ new alpha common.h w/fixes
	+ new test case

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-10-22 18:23 PDT by <grunwald at rushmore.pa.dec.com>.
# Source directory was `/tmp_mnt/n/wrl-nfs1/wrl_user/grunwald/Src/Kaffe/Kaffe'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   6877 -rw-rwsr-- config/alpha/common.h
#   4878 -rw-rw-r-- test/regression/TestNative.java
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh27489; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= config/alpha/common.h ==============
if test ! -d 'config'; then
  $echo 'x -' 'creating directory' 'config'
  mkdir 'config'
fi
if test ! -d 'config/alpha'; then
  $echo 'x -' 'creating directory' 'config/alpha'
  mkdir 'config/alpha'
fi
if test -f 'config/alpha/common.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'config/alpha/common.h' '(file already exists)'
else
  $echo 'x -' extracting 'config/alpha/common.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'config/alpha/common.h' &&
/*
X * alpha/common.h
X * Common Alpha configuration information.
X *
X * Copyright (c) 1996, 1997
X *	Transvirtual Technologies, Inc.  All rights reserved.
X *
X * See the file "license.terms" for information on usage and redistribution 
X * of this file. 
X *
X * 15 July, 1998:
X *      Modified by Rick Greer (rick at sandpiper.com) for use with Alpha Linux
X */
X
#ifndef __alpha_common_h
#define __alpha_common_h
X
/*
X * Make a call to a native or Java (JIT) method.
X *  This assembly code should build a standard C call using the passed
X *  call information.  By its nature this is highly processor specific.
X *  This function is mandatory for the JIT, but can be avoided for
X *  the interpreter if you don't define NO_KAFFE_STUBS.  However, the
X *  Kaffe stubs will be deprecated at some time in the future and
X *  this function will be needed for JNI support when it comes.
X */
#define	NO_KAFFE_STUBS
X
/*
X * For each argument, callsize[n] is either '1' or '2', saying
X * how many words are being used.
X */
X
#define getSingleJavaArg(CALL, n)			      \
(   /*									      \
X     *  Sign-extend short arguments:					      \
X     *									      \
X     *  This macro sign extends short (i.e, 32-bit or less) arguments to a    \
X     *  64-bit "long" that can be inserted directly into a 64-bit register.   \
X     */									      \
X    ((CALL)->callsize[n] == 2) ? (CALL)->args[n].j : (long)((CALL)->args[n].i)\
)
X
X
#undef getSingleJavaArg
#define getSingleJavaArg(CALL, n) (CALL) -> args[n].j
X
/*									      \
*  Sign-extend short arguments:					      \
*									      \
*  This macro sign extends short (i.e, 32-bit or less) arguments to a    \
*  64-bit "long" that can be inserted directly into a 64-bit register.   \
*/									      \
#define getJavaArg(CALL, n, iarg, farg) \
{ \
X    if ( (CALL) -> callsize[n] == 1 ) { \
X      iarg = (long)   ((CALL) -> args[n].i); \
X      farg = (double) ((CALL) ->  args[n].f); \
X    } else { \
X      iarg = (long)   ((CALL) -> args[n].j); \
X      farg = (double) ((CALL) -> args[n].d); \
X    } \
}
X
#define javaArgCase(CALL,_x_,_y_) case _x_: getJavaArg(CALL, (_x_-1), r ## _y_, f ## _y_)
X
#define	sysdepCallMethod(CALL)						      \
{   /*									      \
X     *  Call a Java Method:						      \
X     *									      \
X     *  This macro generates an in-line call to the Java method described by  \
X     *  the given method info structure ("CALL" argument) and stores the      \
X     *  return value in the info struct as well.			      \
X     */									      \
X									      \
X    asm ("" ::: "$9", "$10", "$11"); \
X    asm ("" ::: "$16", "$17", "$18", "$19", "$20", "$21", "$9", "$27", "$26"); \
X    {                                                                         \
X    int x, rags = 0;		    					      \
X    /* The parameter registers ... 					    */\
X    register long r16 asm("$16");					      \
X    register long r17 asm("$17");					      \
X    register long r18 asm("$18");					      \
X    register long r19 asm("$19");					      \
X    register long r20 asm("$20");					      \
X    register long r21 asm("$21");					      \
X									      \
X    register double f16 asm("$f16");					      \
X    register double f17 asm("$f17");					      \
X    register double f18 asm("$f18");					      \
X    register double f19 asm("$f19");					      \
X    register double f20 asm("$f20");					      \
X    register double f21 asm("$f21");					      \
X									      \
X    register unsigned long *osp asm("$9"); \
X    register unsigned long *ogp asm("$10"); \
X    /* any temporary register would do.. */  \
X    register unsigned long *nsp asm("$11"); \
X    register unsigned long* pv asm("$27"); \
X    asm ("mov	$30,%0" : "=r" (osp)); \
X    asm ("mov	$29,%0" : "=r" (ogp)); \
X    nsp = osp;						      \
X    pv = (CALL) -> function;				      \
X    for (x = 0; x < (CALL)->nrargs; x++)				      \
X    {   /*								      \
X         *  The alpha has 64-bit registers, so we don't really need the ex-   \
X         *  tra "callsize = 0" entries in the arg list.  This loop removes    \
X         *  them by sliding any subsequent entries to the left.		      \
X         */								      \
X									      \
X        if ((CALL)->callsize[x] > 0)					      \
X        {								      \
X            if (x > rags) (CALL)->args[rags] = (CALL)->args[x];		      \
X            rags += 1;							      \
X        }								      \
X    }									      \
X									      \
X    {                                                                         \
X									      \
X    switch (rags)							      \
X    {                                                                         \
X        default:							      \
X	  {									\
X        /*		                                                              \
X         * We're doing to hack the frame buffer the difficult way..               \
X         */                                                                       \
X        int margs = rags - 6;        \
X        nsp = osp - margs;  \
X	/* Copy arguments to the stack we allocated */			      \
X	  for (x = 0; x < margs; x++) {						\
X	    nsp[x] = getSingleJavaArg(CALL, x+6);				\
X	  }									\
X        }								      \
X									      \
X        /* The first 6 arguments are loaded into the parameter registers.   */\
X        javaArgCase(CALL,6,21); \
X        javaArgCase(CALL,5,20); \
X        javaArgCase(CALL,4,19); \
X        javaArgCase(CALL,3,18); \
X        javaArgCase(CALL,2,17); \
X        javaArgCase(CALL,1,16); \
X        case 0:  /* nothing */ \
X    }									      \
X    asm volatile ("mov %0,$30" :: "r" (nsp), \
X	/* include all the argument registers least they get DCE'd away */   \
X	"r" (pv), \
X	"r" (r16), "r" (r17), "r" (r18), "r" (r19), "r" (r20), "r" (r21) ); \
X    asm volatile ("\
X         jsr $26,($27),0 \n\
X         ldgp $29,0($26)\n\
X	 mov %0, $30" \
X	 :: "r" (osp), \
X	"f" (f16), "f" (f17), "f" (f18), "f" (f19), "f" (f20), "f" (f21) \
X	 /* and mention that we kill these.. */   \
X	 : \
X		 "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
X		 "$22", "$23", "$24", "$25", "$27", "$26", \
X		 "$f0", "$f1", \
X	          /*  we don't modify the FP callee-saves registers */ \
X	 	  /* "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", */ \
X		 "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
X                 "$f16", "$f17", "$f18", "$f19",  "$f20", "$f21", \
X                 "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", \
X		 "memory"); \
X    }									      \
X    asm ("stq $0,%0" : "=m" ((CALL)->ret->j));				      \
X									      \
X    /* Store floating point return value over (default) integer value ...   */\
X    {									      \
X      char rt = (CALL) -> rettype;									      \
X      if (rt == 'D') asm volatile ("stt $f0,%0" : "=m" ((CALL)->ret->d));    \
X      if (rt == 'F') asm volatile ("sts $f0,%0" : "=m" ((CALL)->ret->f));    \
X    }									      \
X    }									      \
}
#endif
SHAR_EOF
  $shar_touch -am 1022165198 'config/alpha/common.h' &&
  chmod 0664 'config/alpha/common.h' ||
  $echo 'restore of' 'config/alpha/common.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'config/alpha/common.h:' 'MD5 check failed'
5bba8b9d82277cea7cf3af7c38d9a3e7  config/alpha/common.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'config/alpha/common.h'`"
    test 6877 -eq "$shar_count" ||
    $echo 'config/alpha/common.h:' 'original size' '6877,' 'current size' "$shar_count!"
  fi
fi
# ============= test/regression/TestNative.java ==============
if test ! -d 'test'; then
  $echo 'x -' 'creating directory' 'test'
  mkdir 'test'
fi
if test ! -d 'test/regression'; then
  $echo 'x -' 'creating directory' 'test/regression'
  mkdir 'test/regression'
fi
if test -f 'test/regression/TestNative.java' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'test/regression/TestNative.java' '(file already exists)'
else
  $echo 'x -' extracting 'test/regression/TestNative.java' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'test/regression/TestNative.java' &&
/**
X * This test requires native functions.
X * It tests that passing int, long, float, and double parameters works
X * properly.  See libraries/clib/native/TestNative.c
X *
X * This should be very helpful for porters to new architectures who want
X * to debug the sysdepCallMethod macro
X */
public class TestNative
{
X  public static native int test16int(int a, int b, int c, int d,
X				     int e, int f, int g, int h,
X				     int i, int j, int k, int l,
X				     int m, int n, int o, int p);
X
X  public static native long test16long(long a, long b, long c, long d,
X				       long e, long f, long g, long h,
X				       long i, long j, long k, long l,
X				       long m, long n, long o, long p);
X
X  public static native long test16intlong(int a, long b, long c, long d,
X					  long e, long f, long g, long h,
X					  long i, int j, int k, long l,
X					  long m, long n, long o, long p);
X
X  public static native float test16float(float a, float b, float c, float d,
X					 float e, float f, float g, float h,
X					 float i, float j, float k, float l,
X					 float m, float n, float o, float p);
X
X  public static native double test16double(
X					   double a, double b, double c, double d,
X					   double e, double f, double g, double h,
X					   double i, double j, double k, double l,
X					   double m, double n, double o, double p);
X
X  public static native double test16floatdouble(
X						float a, double b, double c, double d,
X						double e, double f, double g, double h,
X						double i, float j, float k, double l,
X						double m, double n, double o, double p);
X
X  public static double fabs(double x)
X  {
X    if ( x < 0 ) {
X      return -x;
X    } else {
X      return x;
X    }
X  }
X
X  public static void main(String av[])
X  {
X    int i_should_be = 0x11111111 + 0x22222222 + 0x33333333 + 0x44444444 +
X      0x55555555 + 0x66666666 + 0x77777777 + 0x88888888 +
X      0x99999999 + 0xAAAAAAAA + 0xBBBBBBBB + 0xCCCCCCCC +
X      0xDDDDDDDD + 0xEEEEEEEE + 0xFFFFFFFF + 0x12345678;
X    System.out.println("Following test results should be " + i_should_be);
X
X    int i = test16int(0x11111111, 0x22222222, 0x33333333, 0x44444444,
X		      0x55555555, 0x66666666, 0x77777777, 0x88888888,
X		      0x99999999, 0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC,
X		      0xDDDDDDDD, 0xEEEEEEEE, 0xFFFFFFFF, 0x12345678
X		      );
X    System.out.print("test16int returned " + i);
X    if ( i == i_should_be ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X
X
X    long l_should_be = 0x11111111 + 0x22222222 + 0x33333333 + 0x44444444 +
X      0x55555555 + 0x66666666 + 0x77777777 + 0x88888888 +
X      0x99999999 + 0xAAAAAAAA + 0xBBBBBBBB + 0xCCCCCCCC +
X      0xDDDDDDDD + 0xEEEEEEEE + 0xFFFFFFFF + 0x12345678;
X    System.out.println("Following test results should be " + l_should_be);
X
X    long l = test16long(0x11111111, 0x22222222, 0x33333333, 0x44444444,
X			0x55555555, 0x66666666, 0x77777777, 0x88888888,
X			0x99999999, 0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC,
X			0xDDDDDDDD, 0xEEEEEEEE, 0xFFFFFFFF, 0x12345678
X			);
X    System.out.print("test16long returned " + l);
X    if ( l == l_should_be ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X
X    long l2_should_be = 1 +(-1) + 2 + (-2) + 3 + (-3) + 4 + (-4) +
X      11 +(-11) + 22 + (-22) + 33 + (-33) + 44 + (-44);
X
X    l = test16intlong(1 ,(-1) , 2 , (-2) , 3 , (-3) , 4 , (-4) ,
X      11 ,(-11) , 22 , (-22) , 33 , (-33) , 44 , (-44));
X
X    System.out.print("test16intlong returned " + l);
X    if ( l == l2_should_be ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X
X    float f_should_be =  -1.2f + 0.2f + 3.3f + 4.5f + 5.6f + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16;
X    System.out.println("Following test results should be " + f_should_be);
X
X    float f = test16float(-1.2f, 0.2f, 3.3f, 4.5f, 5.6f, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
X    System.out.print("test16float returned " + f);
X    if ( f == f_should_be ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X
X    double d_should_be =  -1.2 + 0.2 + 3.3 + 4.5 + 5.6 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16;
X    System.out.println("Following test results should be " + d_should_be);
X
X    double d = test16double(-1.2, 0.2, 3.3, 4.5, 5.6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
X    System.out.print("test16double returned " + d);
X    if ( d == d_should_be ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X
X    d = test16floatdouble(-1.2f, 0.2, 3.3, 4.5,
X			  5.6, 6, 7, 8,
X			  9, 10f, 11f, 12,
X			  13, 14, 15, 16);
X    System.out.print("test16floatdouble returned " + d);
X    if ( fabs(d - d_should_be) < 0.001 ) {
X      System.out.println("...SUCCESS");
X    } else {
X      System.out.println("...FALIURE");
X    }
X  }
}
SHAR_EOF
  $shar_touch -am 1022171298 'test/regression/TestNative.java' &&
  chmod 0664 'test/regression/TestNative.java' ||
  $echo 'restore of' 'test/regression/TestNative.java' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'test/regression/TestNative.java:' 'MD5 check failed'
421c322f09dbef542c84606db40ab28c  test/regression/TestNative.java
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'test/regression/TestNative.java'`"
    test 4878 -eq "$shar_count" ||
    $echo 'test/regression/TestNative.java:' 'original size' '4878,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh27489
exit 0

   






More information about the kaffe mailing list