Logo Search packages:      
Sourcecode: pcc version File versions  Download package

local2.c

/*
 * Copyright (c) 2008 David Crawshaw <david@zentus.com>
 * 
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "pass1.h"
#include "pass2.h"


char *
rnames[] = {
      /* "\%g0", always zero, removed due to 31-element class limit */
              "\%g1", "\%g2", "\%g3", "\%g4", "\%g5", "\%g6", "\%g7",
      "\%o0", "\%o1", "\%o2", "\%o3", "\%o4", "\%o5", "\%o6", "\%o7",
      "\%l0", "\%l1", "\%l2", "\%l3", "\%l4", "\%l5", "\%l6", "\%l7",
      "\%i0", "\%i1", "\%i2", "\%i3", "\%i4", "\%i5", "\%i6", "\%i7",

      "\%f0",  "\%f1",  "\%f2",  "\%f3",  "\%f4",  "\%f5",  "\%f6",  "\%f7",
      "\%f8",  "\%f9",  "\%f10", "\%f11", "\%f12", "\%f13", "\%f14", "\%f15",
      "\%f16", "\%f17", "\%f18", "\%f19", "\%f20", "\%f21", "\%f22", "\%f23",
      "\%f24", "\%f25", "\%f26", "\%f27", "\%f28", "\%f29", "\%f30",
      /*, "\%f31" XXX removed due to 31-element class limit */

      "\%f0",  "\%f2",  "\%f4",  "\%f6",  "\%f8",  "\%f10", "\%f12", "\%f14",
      "\%f16", "\%f18", "\%f20", "\%f22", "\%f24", "\%f26", "\%f28", "\%f30",

      "\%sp", "\%fp",
};

void
deflab(int label)
{
      printf(LABFMT ":\n", label);
}

void
prologue(struct interpass_prolog *ipp)
{
      int i, stack;

      stack = V9RESERVE + V9STEP(p2maxautooff);

      for (i = ipp->ipp_regs[0]; i; i >>= 1)
            if (i & 1)
                  stack += 16;

      /* TODO printf("\t.proc %d\n"); */
      if (ipp->ipp_vis)
            printf("\t.global %s\n", ipp->ipp_name);
      printf("\t.align 4\n");
      printf("%s:\n", ipp->ipp_name);
      if (SIMM13(stack))
            printf("\tsave %%sp,-%d,%%sp\n", stack);
      else {
            printf("\tsetx -%d,%%g4,%%g1\n", stack);
            printf("\tsave %%sp,%%g1,%%sp\n");
      }
}

void
eoftn(struct interpass_prolog *ipp)
{
      printf("\tret\n");
      printf("\trestore\n");
      printf("\t.type %s,#function\n", ipp->ipp_name);
      printf("\t.size %s,(.-%s)\n", ipp->ipp_name, ipp->ipp_name);
}

void
hopcode(int f, int o)
{
      char *str;

      switch (o) {
            case EQ:        str = "brz"; break;
            case NE:        str = "brnz"; break;
            case ULE:
            case LE:        str = "brlez"; break;
            case ULT:
            case LT:        str = "brlz";  break;
            case UGE:
            case GE:        str = "brgez"; break;
            case UGT:
            case GT:        str = "brgz";  break;
            case PLUS:      str = "add"; break;
            case MINUS:     str = "sub"; break;
            case AND:       str = "and"; break;
            case OR:        str = "or";  break;
            case ER:        str = "xor"; break;
            default:
                  comperr("unknown hopcode: %d (with %c)", o, f);
                  return;
      }

      printf("%s%c", str, f);
}

int
tlen(NODE *p)
{
      switch (p->n_type) {
            case CHAR:
            case UCHAR:
                  return 1;
            case SHORT:
            case USHORT:
                  return (SZSHORT / SZCHAR);
            case FLOAT:
                  return (SZFLOAT / SZCHAR);
            case DOUBLE:
                  return (SZDOUBLE / SZCHAR);
            case INT:
            case UNSIGNED:
                  return (SZINT / SZCHAR);
            case LONG:
            case ULONG:
            case LONGLONG:
            case ULONGLONG:
                  return SZLONGLONG / SZCHAR;
            default:
                  if (!ISPTR(p->n_type))
                        comperr("tlen type unknown: %d");
                  return SZPOINT(p->n_type) / SZCHAR;
      }
}

void
zzzcode(NODE * p, int c)
{
      char *str;
      NODE *l, *r;
      l = p->n_left;
      r = p->n_right;

      switch (c) {

      case 'A':   /* Add const. */
            if (ISPTR(l->n_type) && l->n_rval == FP)
                  r->n_lval += V9BIAS;

            if (SIMM13(r->n_lval))
                  expand(p, 0, "\tadd AL,AR,A1\t\t! add const\n");
            else
                  expand(p, 0, "\tsetx AR,A3,A2\t\t! add const\n"
                               "\tadd AL,A2,A1\n");
            break;
      case 'B':   /* Subtract const. */
            if (ISPTR(l->n_type) && l->n_rval == FP)
                  r->n_lval -= V9BIAS;

            if (SIMM13(r->n_lval))
                  expand(p, 0, "\tsub AL,AR,A1\t\t! subtract const\n");
            else
                  expand(p, 0, "\tsetx AR,A3,A2\t\t! subtract const\n"
                               "\tsub AL,A2,A1\n");
            break;
      case 'C':   /* Load constant to register. */
            if (ISPTR(p->n_type))
                  expand(p, 0,
                        "\tsethi %h44(AL),A1\t\t! load label\n"
                        "\tor A1,%m44(AL),A1\n"
                        "\tsllx A1,12,A1\n"
                        "\tor A1,%l44(AL),A1\n");
            else if (SIMM13(p->n_lval))
                  expand(p, 0, "\tor %g0,AL,A1\t\t\t! load const\n");
            else
                  expand(p, 0, "\tsetx AL,A2,A1\t\t! load const\n");
            break;
      case 'F':   /* Floating-point comparison, cf. hopcode(). */
            switch (p->n_op) {
                  case EQ:        str = "fbe"; break;
                  case NE:        str = "fbne"; break;
                  case ULE:
                  case LE:        str = "fbule"; break;
                  case ULT:
                  case LT:        str = "fbul";  break;
                  case UGE:
                  case GE:        str = "fbuge"; break;
                  case UGT:
                  case GT:        str = "fbug";  break;
                  /* XXX
                  case PLUS:      str = "add"; break;
                  case MINUS:     str = "sub"; break;
                  case AND:       str = "and"; break;
                  case OR:        str = "or";  break;
                  case ER:        str = "xor"; break;*/
                  default:
                        comperr("unknown float code: %d", p->n_op);
                        return;
            }
            printf(str);
            break;

      case 'Q':   /* Structure assignment. */
            /* TODO Check if p->n_stsize is small and use a few ldx's
                    to move the struct instead of memcpy. The equiv.
                  could be done on all the architectures. */
            if (l->n_rval != O0)
                  printf("\tmov %s,%s\n", rnames[l->n_rval], rnames[O0]);
            if (SIMM13(p->n_stsize))
                  printf("\tor %%g0,%d,%%o2\n", p->n_stsize);
            else
                  printf("\tsetx %d,%%g1,%%o2\n", p->n_stsize);
            printf("\tcall memcpy\t\t\t! struct assign (dest, src, len)\n");
            printf("\tnop\n");
            break;
      default:
            cerror("unknown zzzcode call: %c", c);
      }
}

int
rewfld(NODE * p)
{
      return (1);
}

int
fldexpand(NODE *p, int cookie, char **cp)
{
      printf("XXX fldexpand called\n"); /* XXX */
      return 1;
}

int
flshape(NODE * p)
{
      return SRREG;
}

int
shtemp(NODE * p)
{
      return 0;
}


void
adrcon(CONSZ val)
{
}

void
conput(FILE * fp, NODE * p)
{
      if (p->n_op != ICON) {
            comperr("conput got bad op: %s", copst(p->n_op));
            return;
      }

      if (p->n_name[0] != '\0') {
            fprintf(fp, "%s", p->n_name);
            if (p->n_lval > 0)
                  fprintf(fp, "+");
            if (p->n_lval)
                  fprintf(fp, CONFMT, p->n_lval);
      } else
            fprintf(fp, CONFMT, p->n_lval);
}

void
insput(NODE * p)
{
      comperr("insput");
}

void
upput(NODE *p, int size)
{
      comperr("upput");
}

void
adrput(FILE * io, NODE * p)
{
      int64_t off;

      if (p->n_op == FLD) {
            printf("adrput a FLD\n");
            p = p->n_left;
      }

      if (p->n_op == UMUL && p->n_right == 0)
            p = p->n_left;

      off = p->n_lval;

      switch (p->n_op) {
      case NAME:
            if (p->n_name[0] != '\0')
                  fputs(p->n_name, io);
            if (off > 0)
                  fprintf(io, "+");
            if (off != 0)
                  fprintf(io, CONFMT, (long long int)off);
            return;
      case OREG:
            fprintf(io, "%s", rnames[p->n_rval]);
            if (p->n_rval == FP)
                  off += V9BIAS;
            if (p->n_rval == SP)
                  off += V9BIAS + V9RESERVE;
            if (off > 0)
                  fprintf(io, "+");
            if (off)
                  fprintf(io, CONFMT, (CONSZ)off);
            return;
      case ICON:
            /* addressable value of the constant */
            conput(io, p);
            return;
      case REG:
            fputs(rnames[p->n_rval], io);
            return;
      case FUNARG:
            /* We do something odd and store the stack offset in n_rval. */
            fprintf(io, "%d", V9BIAS + V9RESERVE + p->n_rval);
            return;
      default:
            comperr("bad address, %s, node %p", copst(p->n_op), p);
            return;
      }
}

void
cbgen(int o, int lab)
{
}

void
myreader(struct interpass * ipole)
{
}

void
mycanon(NODE * p)
{
}

void
myoptim(struct interpass * ipole)
{
}

void
rmove(int s, int d, TWORD t)
{
      printf("\t");

      if (t == FLOAT)         printf("fmovs");
      else if (t == DOUBLE) printf("fmovd");
      else                  printf("mov");

      printf(" %s,%s\t\t\t! rmove()\n", rnames[s], rnames[d]);
}

int
gclass(TWORD t)
{
      if (t == FLOAT)
            return CLASSB;
      if (t == DOUBLE)
            return CLASSC;
      return CLASSA;
}

void
lastcall(NODE *p)
{
}

int
special(NODE *p, int shape)
{
      return SRNOPE;
}

void mflags(char *str)
{
}

int
COLORMAP(int c, int *r)
{
      int num=0;

      switch (c) {
            case CLASSA:
                  num += r[CLASSA];
                  return num < 32;
            case CLASSB:
                  num += r[CLASSB];
                  num += 2*r[CLASSC];
                  return num < 32;;
            case CLASSC:
                  num += r[CLASSC];
                  num += 2*r[CLASSB];
                  return num < 17;
            case CLASSD:
                  return 0;
            default:
                  comperr("COLORMAP: unknown class: %d", c);
                  return 0;
      }
}
/*
 * Do something target-dependent for xasm arguments.
 * Supposed to find target-specific constraints and rewrite them.
 */
int
myxasm(struct interpass *ip, NODE *p)
{
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index