DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T o

⟦b16064482⟧ TextFile

    Length: 6295 (0x1897)
    Types: TextFile
    Names: »out-convex.c«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦d53cfc7b2⟧ »./gcc-1.35.tar.Z« 
        └─⟦90f628c1d⟧ 
            └─⟦this⟧ »gcc-1.35/config/out-convex.c« 

TextFile

/* Subroutines for insn-output.c for Convex.
   Copyright (C) 1989 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/*
 *  set_cmp (left_rtx, right_rtx, [bhwlsd])
 *  gen_cmp (label_rtx, cmpop, [tf])
 *
 *  set_cmp saves the operands of a "cmp" insn,
 *    along with the type character to be used in the compare instruction.
 *
 *  gen_cmp finds out what comparison is to be performed and
 *    outputs the necessary instructions, eg,
 *    "eq.w a1,a2 ! jbra.t L5"
 *    for (cmpsi a1 a2) (beq L5)
 */
 
static rtx xop0, xop1;
static char typech, regch;

char *
set_cmp (op0, op1, typechr)
     rtx op0, op1;
     char typechr;
{
  xop0 = op0;
  xop1 = op1;
  typech = typechr;
  if (GET_CODE (op0) == REG)
    regch = REGNO_OK_FOR_BASE_P (REGNO (op0)) ? 'a' : 's';
  else if (GET_CODE (op1) == REG)
    regch = REGNO_OK_FOR_BASE_P (REGNO (op1)) ? 'a' : 's';
  else abort ();
  return "";
}

char *
gen_cmp (label, cmpop, tf)
     rtx label;
     char *cmpop;
     char tf;
{
  char buf[80];
  char revop[4];
  rtx ops[3];

  ops[2] = label;

  /* constant must be first; swap operands if necessary
     if lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
     and reverse the sense of the jump */

  if (CONSTANT_P (xop1) || GET_CODE (xop1) == CONST_DOUBLE)
    {
      ops[0] = xop1;
      ops[1] = xop0;
      if (cmpop[0] == 'l')
	{
	  bcopy (cmpop, revop, 4);
	  revop[1] ^= 'e' ^ 't';
	  tf ^= 't' ^ 'f';
	  cmpop = revop;
	}
    }
  else
    {
      ops[0] = xop0;
      ops[1] = xop1;
    }

  sprintf (buf, "%s.%c %%0,%%1\n\tjbr%c.%c %%l2", cmpop, typech, regch, tf);
  output_asm_insn (buf, ops);
  return "";
}
\f


/*
 *  set_section -- arg is a section name, like ".text".  
 *	Remembers it and returns it
 *
 *  align_section -- returns a string to align current section,
 *	something like ".text 2" or ".align 8".  Arg is log2 of boundary.
 */

static char *prevsect = "";
static char *cursect = "";

char *
set_section (p)
     char *p;
{
  if (p == 0)
    p = prevsect;
  prevsect = cursect;
  cursect = p;
  return p;
}

char *
align_section (n)
     int n;
{
  static char buf[20];

  if (n < 0)
    {
      /* -n is a size; align to that size */
      if ((n & 7) == 0) n = 3;
      else if ((n & 3) == 0) n = 2;
      else if ((n & 1) == 0) n = 1;
      else n = 0;
    }

  if (!strcmp (cursect, ".text"))
    {
      if (n > 1)
	sprintf (buf, "%s %d\n", cursect, n);
      else
	sprintf (buf, "%s\n.align %d\n", cursect, 1 << n);
      return buf;
    }
  else
    {
      if (n == 0) return "";
      sprintf (buf, ".align %d\n", 1 << n);
      return buf;
    }
}
\f


/*
 *  pick target machine if not specified, the same as the host
 */

extern int target_flags;

override_options ()
{
#ifdef convex
#include <sys/sysinfo.h>    
  if (! (TARGET_C1 || TARGET_C2))
    {
      struct system_information sysinfo;
      getsysinfo (sizeof sysinfo, &sysinfo);
      if (sysinfo.cpu_type >= SI_CPUTYPE_C2MP)
	target_flags |= 2;
      else
	target_flags |= 1;
    }
#endif
}
\f


/*
 * Routines to look at CONST_DOUBLEs without sinful knowledge of
 * what the inside of u.d looks like
 *
 * const_double_high_int  -- high word of machine double or long long
 * const_double_low_int   -- low word
 * const_double_float_int -- the word of a machine float
 */

static double frexp ();
static void float_extract ();

int
const_double_high_int (x)
     rtx x;
{
  if (GET_MODE (x) == DImode)
    return CONST_DOUBLE_HIGH (x);
  else
    {
      int sign, expd, expf;
      unsigned fracdh, fracdl, fracf;
      float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);

      if (fracdh == 0)
	return 0;
      if (expd < -01777 || expd > 01777)
	return 1 << 31;
      return sign << 31 | (expd + 02000) << 20 | fracdh - (1 << 20);
    }
}

int
const_double_low_int (x)
     rtx x;
{
  if (GET_MODE (x) == DImode)
    return CONST_DOUBLE_LOW (x);
  else
    {
      int sign, expd, expf;
      unsigned fracdh, fracdl, fracf;
      float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);
      return fracdl;
    }
}

int
const_double_float_int (x)
     rtx x;
{
  int sign, expd, expf;
  unsigned fracdh, fracdl, fracf;
  float_extract (x, &sign, &expd, &fracdh, &fracdl, &expf, &fracf);

  if (fracf == 0)
    return 0;
  if (expf < -0177 || expf > 0177)
    return 1 << 31;
  return sign << 31 | (expf + 0200) << 20 | fracf - (1 << 23);
}

#define T21  ((double) (1 << 21))
#define T24  ((double) (1 << 24))
#define T53  ((double) (1 << 27) * (double) (1 << 26))

static void
float_extract (x, sign, expd, fracdh, fracdl, expf, fracf)
     rtx x;
     int *sign, *expd, *expf;
     unsigned *fracdh, *fracdl, *fracf;
{
  int exp, round;
  double d, r;
  union real_extract u;

  bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);

  /* Get sign and exponent.  */

  if (*sign = u.d < 0)
    u.d = -u.d;
  d = frexp (u.d, &exp);  

  /* Get 21 fraction bits for high word and 32 for low word.  */

  for (round = 0; ; round = 1)
    {
      r = frexp (round ? d + 1.0 / T53 : d, expd);
      *expd += exp;
      *fracdh = r * T21;
      *fracdl = (r - *fracdh / T21) * T53;
      if (round || ((r - *fracdh / T21) - *fracdl / T53) < 0.5 * T53)
	break;
    }

  /* Get 24 bits for float fraction. */

  for (round = 0; ; round = 1)
    {
      r = frexp (round ? d + 1.0 / T24 : d, expf);
      *expf += exp;
      *fracf = r * T24;
      if (round || (r - *fracf / T24) < 0.5 * T24)
	break;
    }
}

static double
frexp (d, exp)
     double d;
     int *exp;
{
  int e = 0;

  if (d > 0)
    {
      while (d < 0.5) d *= 2.0, e--;
      while (d >= 1.0) d /= 2.0, e++;
    }

  *exp = e;
  return d;
}