diff options
author | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-01-24 18:47:07 +0000 |
---|---|---|
committer | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-01-24 18:47:07 +0000 |
commit | c82ba39d1b38fa096a175a3f76738285d73ab78c (patch) | |
tree | 65b61374e478b1a82c3961010d7b1df7f6edcede | |
parent | 763605a4912c725592ba8571c8460a71847b1375 (diff) |
Work-in-progress for sparc64, by David Crawshaw.
-rw-r--r-- | usr.bin/pcc/sparc64/code.c | 149 | ||||
-rw-r--r-- | usr.bin/pcc/sparc64/local.c | 282 | ||||
-rw-r--r-- | usr.bin/pcc/sparc64/local2.c | 359 | ||||
-rw-r--r-- | usr.bin/pcc/sparc64/macdefs.h | 206 | ||||
-rw-r--r-- | usr.bin/pcc/sparc64/order.c | 97 | ||||
-rw-r--r-- | usr.bin/pcc/sparc64/table.c | 632 |
6 files changed, 1725 insertions, 0 deletions
diff --git a/usr.bin/pcc/sparc64/code.c b/usr.bin/pcc/sparc64/code.c new file mode 100644 index 00000000000..442077844b3 --- /dev/null +++ b/usr.bin/pcc/sparc64/code.c @@ -0,0 +1,149 @@ +/* + * 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" + +void +defloc(struct symtab *sp) +{ + static char *loctbl[] = { "text", "data", "rodata" }; + static int lastloc = -1; + TWORD t; + int s; + + t = sp->stype; + s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA; + if (s != lastloc) + printf("\n\t.section \".%s\"\n", loctbl[s]); + lastloc = s; + if (s == PROG) + return; + printf("\t.align 4\n"); + if (sp->sclass == EXTDEF) + printf("\t.global %s\n", sp->soname); + if (sp->slevel == 0) { + printf("\t.type %s,#object\n", sp->soname); + printf("\t.size %s," CONFMT "\n", sp->soname, + tsize(sp->stype, sp->sdf, sp->ssue) / SZCHAR); + printf("%s:\n", sp->soname); + } else + printf(LABFMT ":\n", sp->soffset); +} + +void +efcode() +{ + /* XXX */ +} + +void +bfcode(struct symtab **sp, int cnt) +{ + int i; + NODE *p, *q; + struct symtab *sym; + + for (i=0; i < cnt && i < I7 - I0; i++) { + sym = sp[i]; + q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->ssue); + q->n_rval = i + I0; + p = tempnode(0, sym->stype, sym->sdf, sym->ssue); + sym->soffset = regno(p); + sym->sflags |= STNODE; + p = buildtree(ASSIGN, p, q); + ecomp(p); + } + + if (i < cnt) + cerror("unprocessed arguments in bfcode"); /* TODO */ +} + +void +bccode() +{ + SETOFF(autooff, SZINT); +} + +void +ejobcode(int flag) +{ +} + +void +bjobcode() +{ +} + +static NODE * +moveargs(NODE *p, int *regp) +{ + NODE *r, *q; + + if (p->n_op == CM) { + p->n_left = moveargs(p->n_left, regp); + r = p->n_right; + } else { + r = p; + } + + if (*regp > I7 && r->n_op != STARG) + cerror("reg > I7 in moveargs"); /* TODO */ + else if (r->n_op == STARG) + cerror("op STARG in moveargs"); + else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) + cerror("FP in moveargs"); + else if (r->n_type == FLOAT) + cerror("FP in moveargs"); + else { + /* Argument can fit in O0...O7. */ + q = block(REG, NIL, NIL, r->n_type, r->n_df, r->n_sue); + q->n_rval = (*regp)++; + r = buildtree(ASSIGN, q, r); + } + + if (p->n_op == CM) { + p->n_right = r; + return p; + } + + return r; +} + +NODE * +funcode(NODE *p) +{ + int reg = O0; + p->n_right = moveargs(p->n_right, ®); + return p; +} + +int +fldal(unsigned int t) +{ + uerror("illegal field type"); + return ALINT; +} + +void +fldty(struct symtab *p) +{ +} + +int +mygenswitch(int num, TWORD type, struct swents **p, int n) +{ + return 0; +} diff --git a/usr.bin/pcc/sparc64/local.c b/usr.bin/pcc/sparc64/local.c new file mode 100644 index 00000000000..a1a002933db --- /dev/null +++ b/usr.bin/pcc/sparc64/local.c @@ -0,0 +1,282 @@ +/* + * 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" + +NODE * +clocal(NODE *p) +{ + struct symtab *sp; + int op; + NODE *r, *l; + + op = p->n_op; + sp = p->n_sp; + l = p->n_left; + r = p->n_right; + +#ifdef PCC_DEBUG + if (xdebug) { + printf("clocal in: %p, %s\n", p, copst(op)); + fwalk(p, eprint, 0); + } +#endif + + switch (op) { + + case NAME: + if (sp->sclass == PARAM || sp->sclass == AUTO) { + /* + * Use a fake structure reference to + * write out frame pointer offsets. + */ + l = block(REG, NIL, NIL, PTR+STRTY, 0, 0); + l->n_lval = 0; + l->n_rval = FP; + r = p; + p = stref(block(STREF, l, r, 0, 0, 0)); + } + break; + case PCONV: + if (p->n_type > BTMASK && l->n_type > BTMASK) { + /* Remove unnecessary pointer conversions. */ + l->n_type = p->n_type; + l->n_qual = p->n_qual; + l->n_df = p->n_df; + l->n_sue = p->n_sue; + nfree(p); + p = l; + } + break; + + case SCONV: + if (l->n_op == NAME || l->n_op == UMUL || l->n_op == TEMP) { + if ((p->n_type & TMASK) == 0 && + (l->n_type & TMASK) == 0 && + btdims[p->n_type].suesize == + btdims[l->n_type].suesize) { + /* XXX: skip if FP? */ + l->n_type = p->n_type; + nfree(p); + p = l; + } + break; + } + + if (l->n_op != ICON) + break; + + if (ISPTR(p->n_type)) { + l->n_type = p->n_type; + nfree(p); + p = l; + break; + } + + switch (p->n_type) { + case BOOL: l->n_lval = (l->n_lval != 0); break; + case CHAR: l->n_lval = (char)l->n_lval; break; + case UCHAR: l->n_lval = l->n_lval & 0377; break; + case SHORT: l->n_lval = (short)l->n_lval; break; + case USHORT: l->n_lval = l->n_lval & 0177777; break; + case UNSIGNED: + case ULONG: l->n_lval = l->n_lval & 0xffffffff; break; + case LONG: + case INT: l->n_lval = (int)l->n_lval; break; + case ULONGLONG: l->n_lval = l->n_lval; break; + case LONGLONG: l->n_lval = (long long)l->n_lval; break; + case VOID: + break; + default: + cerror("sconv type unknown %d", p->n_type); + } + + l->n_type = p->n_type; + nfree(p); + p = l; + break; + + case PMCONV: + case PVCONV: + if (r->n_op != ICON) + cerror("converting bad type"); + nfree(p); + p = buildtree(op == PMCONV ? MUL : DIV, l, r); + break; + + case FORCE: + /* Put attached value into the return register. */ + p->n_op = ASSIGN; + p->n_right = p->n_left; + p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT)); + p->n_left->n_rval = I0; /* XXX adjust for float/double */ + break; + } + +#ifdef PCC_DEBUG + if (xdebug) { + printf("clocal out: %p, %s\n", p, copst(op)); + fwalk(p, eprint, 0); + } +#endif + + return p; +} + +void +myp2tree(NODE *p) +{ +} + +int +andable(NODE *p) +{ + return 1; +} + +void +cendarg() +{ + autooff = AUTOINIT; +} + +int +cisreg(TWORD t) +{ + /* SPARCv9 registers are all 64-bits wide. */ + return 1; +} + +NODE * +offcon(OFFSZ off, TWORD t, union dimfun *d, struct suedef *sue) +{ + return bcon(off / SZCHAR); +} + +void +spalloc(NODE *t, NODE *p, OFFSZ off) +{ +} + +void +inwstring(struct symtab *sp) +{ +} + +void +instring(struct symtab *sp) +{ + char *s, *str; + + defloc(sp); + str = sp->sname; + + printf("\t.ascii \""); + for (s = str; *s != 0; *s++) { + if (*s == '\\') + esccon(&s); + if (s - str > 60) { + fwrite(str, 1, s - str, stdout); + printf("\"\n\t.ascii \""); + str = s; + } + } + fwrite(str, 1, s - str, stdout); + printf("\\0\"\n"); +} + +void +zbits(OFFSZ off, int fsz) +{ +} + +void +infld(CONSZ off, int fsz, CONSZ val) +{ +} + +void +ninval(CONSZ off, int fsz, NODE *p) +{ + if (p->n_op != ICON && p->n_op != FCON) + cerror("ninval: not a constant"); + if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(p->n_type) != INT) + cerror("ninval: not constant"); + + switch (DEUNSIGN(p->n_type)) { + case CHAR: + printf("\t.align 1\n"); + printf("\t.byte %d\n", (int)p->n_lval & 0xff); + break; + case SHORT: + printf("\t.align 2\n"); + printf("\t.half %d\n", (int)p->n_lval &0xffff); + break; + case BOOL: + p->n_lval = (p->n_lval != 0); /* FALLTHROUGH */ + case INT: + printf("\t.align 4\n\t.long " CONFMT "\n", p->n_lval); + break; + case LONGLONG: + printf("\t.align 8\n\t.xword %lld\n", p->n_lval); + break; + /* TODO FP float and double */ + } +} + +char * +exname(char *p) +{ + return p ? p : ""; +} + +TWORD +ctype(TWORD type) +{ + return type; +} + +void +calldec(NODE *p, NODE *q) +{ +} + +void +extdec(struct symtab *q) +{ +} + +void +defzero(struct symtab *sp) +{ + int off = (tsize(sp->stype, sp->sdf, sp->ssue) + SZCHAR - 1) / SZCHAR; + printf("\t.comm "); + if (sp->slevel == 0) + printf("%s,%d\n", exname(sp->soname), off); + else + printf(LABFMT ",%d\n", sp->soffset, off); +} + +int +mypragma(char **ary) +{ + return 0; +} + +void +fixdef(struct symtab *sp) +{ +} diff --git a/usr.bin/pcc/sparc64/local2.c b/usr.bin/pcc/sparc64/local2.c new file mode 100644 index 00000000000..179a7c78af5 --- /dev/null +++ b/usr.bin/pcc/sparc64/local2.c @@ -0,0 +1,359 @@ +/* + * 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" + +/* + * Many arithmetic instructions take 'reg_or_imm' in SPARCv9, where imm + * means we can use a signed 13-bit constant (simm13). This gives us a + * shortcut for small constants, instead of loading them into a register. + * Special handling is required because 13 bits lies between SSCON and SCON. + */ +#define SIMM13(val) (val < 4096 && val > -4097) + +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", + + "\%sp", "\%fp", + + "\%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 */ +}; + +void +deflab(int label) +{ + printf(LABFMT ":\n", label); +} + +void +prologue(struct interpass_prolog *ipp) +{ + int i, stack; + + /* + * SPARCv9 has a 2047 bit stack bias. Looking at output asm from gcc + * suggests this means we need a base 192 bit offset for %sp. Further + * steps need to be 8-byte aligned. + */ + stack = 192 + p2maxautooff + (p2maxautooff % 8); + + for (i=ipp->ipp_regs; i; i >>= 1) + if (i & 1) + stack += 8; + + /* TODO printf("\t.proc %d\n"); */ + printf("\t.global %s\n", ipp->ipp_name); + printf("\t.align 4\n"); + printf("%s:\n", ipp->ipp_name); + printf("\tsave %%sp,-%d,%%sp\n", stack); +} + +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 DOUBLE: + return (SZDOUBLE / SZCHAR); + case INT: + case UNSIGNED: + case LONG: + case ULONG: + return (SZINT / SZCHAR); + 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) +{ + switch (c) { + + case 'A': /* Load constant to register. */ + if (!ISPTR(p->n_type) && SIMM13(p->n_lval)) + expand(p, 0, "\tor %g0,AL,A1\t\t\t! load const\n"); + else { + expand(p, 0, + "\tsethi %h44(AL),A1\t\t! load const\n" + "\tor A1,%m44(AL),A1\n" + "\tsllx A1,12,A1\n" + "\tor A1,%l44(AL),A1\n"); + } + break; + case 'B': /* Subtract const, store in temp. */ + /* + * If we are dealing with a stack location, SPARCv9 has a + * stack offset of +2047 bits. This is mostly handled by + * notoff(), but when passing as an argument this op is used. + */ + if (ISPTR(p->n_left->n_type) && p->n_left->n_rval == FP) + p->n_right->n_lval -= 2047; + + if (SIMM13(p->n_right->n_lval)) + expand(p, 0, "\tsub AL,AR,A1\t\t! subtract const"); + else { + expand(p, 0, + "\tsethi %h44(AR),%g1\t\t! subtract const\n" + "\tor %g1,%m44(AR),%g1\n" + "\tsllx %g1,12,%g1\n" + "\tor %g1,%l44(AR),%g1\n" + "\tsub AL,%g1,A1\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) { + comperr("conput: negative offset (%lld) on label %s\n", + p->n_lval, p->n_name); + return; + } + if (p->n_lval) + fprintf(fp, "+%lld", 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, off); + return; + case OREG: + fprintf(io, "%s", rnames[p->n_rval]); + /* SPARCv9 stack bias adjustment. */ + if (p->n_rval == FP) + off += 2047; + if (off > 0) + fprintf(io, "+"); + if (off) + fprintf(io, "%lld", off); + return; + case ICON: + /* addressable value of the constant */ + conput(io, p); + return; + case MOVE: + case REG: + fputs(rnames[p->n_rval], io); + 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("\tmov %s,%s\t\t\t! rmove()\n", rnames[s], rnames[d]); +} + +int +gclass(TWORD t) +{ + return (t == FLOAT || t == DOUBLE || t == LDOUBLE) ? CLASSC : 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: + return 0; + case CLASSC: + num += r[CLASSC]; + return num < 32; + default: + comperr("COLORMAP: unknown class"); + return 0; + } +} diff --git a/usr.bin/pcc/sparc64/macdefs.h b/usr.bin/pcc/sparc64/macdefs.h new file mode 100644 index 00000000000..3e392233e61 --- /dev/null +++ b/usr.bin/pcc/sparc64/macdefs.h @@ -0,0 +1,206 @@ +/* + * 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. + */ + +#define makecc(val,i) lastcon = (lastcon<<8)|((val<<24)>>24); + +#define ARGINIT (7*8) /* XXX */ +#define AUTOINIT (0) + +/* Type sizes */ +#define SZCHAR 8 +#define SZBOOL 32 +#define SZINT 32 +#define SZFLOAT 32 +#define SZDOUBLE 64 +#define SZLDOUBLE 64 +#define SZLONG 32 +#define SZSHORT 16 +#define SZLONGLONG 64 +#define SZPOINT(t) 64 + +/* Type alignments */ +#define ALCHAR 8 +#define ALBOOL 32 +#define ALINT 32 +#define ALFLOAT 32 +#define ALDOUBLE 64 +#define ALLDOUBLE 64 +#define ALLONG 32 +#define ALLONGLONG 64 +#define ALSHORT 16 +#define ALPOINT 32 +#define ALSTRUCT 32 +#define ALSTACK 64 + +/* Min/max values. */ +#define MIN_CHAR -128 +#define MAX_CHAR 127 +#define MAX_UCHAR 255 +#define MIN_SHORT -32768 +#define MAX_SHORT 32767 +#define MAX_USHORT 65535 +#define MIN_INT -1 +#define MAX_INT 0x7fffffff +#define MAX_UNSIGNED 0xffffffff +#define MIN_LONG MIN_INT +#define MAX_LONG MAX_INT +#define MAX_ULONG MAX_UNSIGNED +#define MIN_LONGLONG 0x8000000000000000LL +#define MAX_LONGLONG 0x7fffffffffffffffLL +#define MAX_ULONGLONG 0xffffffffffffffffULL + +#define BOOL_TYPE INT +#define WCHAR_TYPE INT + +typedef long long CONSZ; +typedef unsigned long long U_CONSZ; +typedef long long OFFSZ; + +#define CONFMT "%lld" +#define LABFMT "L%d" +#define STABLBL "LL%d" + +#define BACKAUTO /* Stack grows negatively for automatics. */ +#define BACKTEMP /* Stack grows negatively for temporaries. */ + +#undef FIELDOPS +#define RTOLBYTES + +#define ENUMSIZE(high,low) INT +#define BYTEOFF(x) ((x)&03) +#define BITOOR(x) (x) + +#define szty(t) (((t) == DOUBLE || (t) == FLOAT || \ + (t) == LONGLONG || (t) == ULONGLONG) ? 2 : 1) + + +/* Register names. */ + +#define MAXREGS (31 + 2 + 31) +#define NUMCLASS 3 + +//define G0 -1 +#define G1 0 +#define G2 1 +#define G3 2 +#define G4 3 +#define G5 4 +#define G6 5 +#define G7 6 +#define O0 7 +#define O1 8 +#define O2 9 +#define O3 10 +#define O4 11 +#define O5 12 +#define O6 13 +#define O7 14 +#define L0 15 +#define L1 16 +#define L2 17 +#define L3 18 +#define L4 19 +#define L5 20 +#define L6 21 +#define L7 22 +#define I0 23 +#define I1 24 +#define I2 25 +#define I3 26 +#define I4 27 +#define I5 28 +#define I6 29 +#define I7 30 + +#define SP 31 +#define FP 32 +/* +#define F0 33 +#define F1 34 +#define F2 35 +#define F3 36 +#define F4 37 +#define F5 38 +#define F6 39 +#define F7 40 +#define F8 41 +#define F9 42 +#define F10 43 +#define F11 44 +#define F12 45 +#define F13 46 +#define F14 47 +#define F15 48 +#define F16 49 +#define F17 50 +#define F18 51 +#define F19 52 +#define F20 53 +#define F21 54 +#define F22 55 +#define F23 56 +#define F24 57 +#define F25 58 +#define F26 59 +#define F27 60 +#define F28 61 +#define F29 62 +#define F30 63 +*/ + +#define FPREG FP + +#define RETREG(x) ((x)==DOUBLE || (x)==LDOUBLE || (x)==FLOAT ? 33 : O0) + +#define RSTATUS \ + /* global */ \ + SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, \ + SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, SAREG|PERMREG, \ + /* out */ \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + /* local */ \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + /* in */ \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, SAREG|TEMPREG, \ + /* sp */ 0, \ + /* fp */ 0, \ + /* FP */ \ + SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, \ + SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, \ + SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, \ + SBREG, SBREG, SBREG, SBREG, SBREG, SBREG, SBREG /*, SBREG */ + +#define ROVERLAP \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, \ + { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 } /*, { -1 } */ + +#define GCLASS(x) (x < 32 ? CLASSA : (x < 34 ? CLASSB : CLASSC)) +#define PCLASS(p) (1 << gclass((p)->n_type)) +#define DECRA(x,y) (((x) >> (y*6)) & 63) /* decode encoded regs XXX */ +#define ENCRA(x,y) ((x) << (6+y*6)) /* encode regs in int XXX */ +#define ENCRD(x) (x) /* Encode dest reg in n_reg */ + +int COLORMAP(int c, int *r); diff --git a/usr.bin/pcc/sparc64/order.c b/usr.bin/pcc/sparc64/order.c new file mode 100644 index 00000000000..271620937b0 --- /dev/null +++ b/usr.bin/pcc/sparc64/order.c @@ -0,0 +1,97 @@ +/* + * 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 "pass2.h" + +int +notoff(TWORD t, int r, CONSZ off, char *cp) +{ + return 0; +} + +/* + * Turn a UMUL-referenced node into OREG. + */ +void +offstar(NODE *p, int shape) +{ + if (x2debug) + printf("offstar(%p)\n", p); + + if (p->n_op == PLUS || p->n_op == MINUS) { + if (p->n_right->n_op == ICON) { + if (isreg(p->n_left) == 0) + (void)geninsn(p->n_left, INAREG); + /* Converted in ormake() */ + return; + } + } + (void)geninsn(p, INAREG); +} + +void +myormake(NODE *q) +{ +} + +int +shumul(NODE *p) +{ + return SOREG; +} + +int +setbin(NODE *p) +{ + return 0; +} + +int +setasg(NODE *p, int cookie) +{ + return 0; +} + +int +setuni(NODE *p, int cookie) +{ + return 0; +} + +struct rspecial * +nspecial(struct optab *q) +{ + return 0; /* XXX */ +} + +int +setorder(NODE *p) +{ + return 0; +} + +int * +livecall(NODE *p) +{ + static int ret[] = { O0, O1, O2, O3, O4, O5, O6, O7, -1 }; + return ret; +} + +int +acceptable(struct optab *op) +{ + return 1; +} diff --git a/usr.bin/pcc/sparc64/table.c b/usr.bin/pcc/sparc64/table.c new file mode 100644 index 00000000000..104ef4d3937 --- /dev/null +++ b/usr.bin/pcc/sparc64/table.c @@ -0,0 +1,632 @@ +/* + * 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 "pass2.h" + +#define TUWORD TUNSIGNED|TULONG +#define TSWORD TINT|TLONG +#define TWORD TUWORD|TSWORD + +struct optab table[] = { + +{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", }, /* empty */ + +{ PCONV, INAREG, + SAREG, TWORD|TPOINT, + SAREG, TWORD|TPOINT, + 0, RLEFT, + " ! convert between word and pointer\n", }, + +/* Conversions. TODO: check zeroing on down conversions and signed/unsigned */ + +{ SCONV, INAREG, + SOREG, TCHAR, + SAREG, TSWORD|TSHORT, + NAREG, RESC1, + " ldsb [AL],A1 ! int8->int16/int32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TCHAR, + SAREG, TUWORD|TUSHORT|TUCHAR, + NAREG, RESC1, + " ldub [AL],A1 ! int8 -> uint16/uint32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TUCHAR, + SAREG, TWORD|TSHORT|TUSHORT, + NAREG, RESC1, + " ldub [AL],A1 ! int8 -> (u)int16/(u)int32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TCHAR, + SAREG, TLONGLONG, + NAREG, RESC1, + " ldsb [AL],A1 ! int8 -> int64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TUCHAR, + SAREG, TLONGLONG|TULONGLONG, + NAREG, RESC1, + " ldub [AL],A1 ! uint8 -> (u)int64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT|TUSHORT, + SAREG, TCHAR, + NAREG, RESC1, + " ldsh [AL],A1 ! (u)int16 -> int8\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT|TUSHORT, + SAREG, TUCHAR, + NAREG, RESC1, + " ldsh [AL],A1 ! (u)int16 -> uint8\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT, + SAREG, TSWORD, + NAREG, RESC1, + " ldsh [AL],A1 ! int16 -> int32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT, + SAREG, TUWORD, + NAREG, RESC1, + " lduh [AL],A1 ! int16 -> uint32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TUSHORT, + SAREG, TWORD, + NAREG, RESC1, + " lduh [AL],A1 ! uint16 -> int32\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT, + SAREG, TLONGLONG, + NAREG, RESC1, + " ldsh [AL],A1 ! int16 -> int64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSHORT, + SAREG, TULONGLONG, + NAREG, RESC1, + " lduh [AL],A1 ! int16 -> uint64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TUSHORT, + SAREG, TLONGLONG|TULONGLONG, + NAREG, RESC1, + " lduh [AL],A1 ! uint16 -> uint64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TWORD, + SAREG, TCHAR, + NAREG, RESC1, + " ldsw [AL],A1 ! int32 -> int8\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TWORD, + SAREG, TUCHAR, + NAREG, RESC1, + " lduw [AL],A1 ! int32 -> uint8\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TWORD, + SAREG, TSHORT, + NAREG, RESC1, + " ldsw [AL],A1 ! int32 -> int16\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TWORD, + SAREG, TUSHORT, + NAREG, RESC1, + " lduw [AL],A1 ! int32 -> uint16\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TSWORD, + SAREG, TLONGLONG|TULONGLONG, + NAREG, RESC1, + " ldsw [AL],A1 ! int32 -> (u)int64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TUWORD, + SAREG, TLONGLONG|TULONGLONG, + NAREG, RESC1, + " lduw [AL],A1 ! int32 -> (u)int64\n" + " nop\n", }, + +{ SCONV, INAREG, + SOREG, TLONGLONG|TULONGLONG, + SAREG, TCHAR|TUCHAR|TSHORT|TUSHORT|TWORD, + NAREG, RESC1, + " ldx [AL],A1 ! int64 -> (u)int8/16/32\n" + " nop\n", }, + +/* XXX This op is catching all register-to-register conversions. Some of these + * need special handling. */ + +{ SCONV, INAREG, + SAREG, TANY, + SAREG, TANY, + 0, RLEFT, + " \t\t! XXX in-register convert\n", }, + + +/* Multiplication and division */ + +{ MUL, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG|NASR|NASL, RESC1, + " mulx AL,AR,AR ! multiply\n", }, + +{ DIV, INAREG, + SAREG, TUWORD|TUSHORT|TUCHAR|TULONGLONG, + SAREG, TUWORD|TUSHORT|TUCHAR|TULONGLONG, + NAREG|NASR|NASL, RESC1, + " udivx AL,AR,AR ! unsigned division\n", }, + +{ DIV, INAREG, + SAREG, TWORD|TSHORT|TCHAR|TLONGLONG, + SAREG, TWORD|TSHORT|TCHAR|TLONGLONG, + NAREG|NASR|NASL, RESC1, + " sdivx AL,AR,AR ! signed division\n", }, + + /* TODO MOD */ + +{ PLUS, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG|NASL, RESC1, + " add A1,AL,AR\n", }, + +{ PLUS, INAREG, + SAREG, TANY, + SCCON, TWORD, + NAREG|NASL, RESC1, + " add AL,AR,A1 ! add constant to reg\n", }, + +{ MINUS, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG|NASL, RESC1, + " sub AL,AR,AR\n", }, + +{ MINUS, INAREG, + SAREG, TANY, + SSCON, TANY, + NAREG|NASL, RESC1, + "ZB\n", }, + +{ UMINUS, INAREG, + SAREG, TANY, + SANY, TANY, + NAREG|NASL, RESC1, + " sub A1,AL,A1\n", }, + +/* Shifts */ + +{ RS, INAREG, + SAREG, TSWORD|TSHORT|TCHAR, + SANY, TANY, + NAREG|NASL, RESC1, + " sra AL,AR,AL ! shift right\n", }, + +{ RS, INAREG, + SAREG, TLONGLONG|TULONGLONG, + SANY, TANY, + NAREG|NASL, RESC1, + " srax AL,AR,AL ! shift right\n", }, + +{ LS, INAREG, + SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR, + SANY, TANY, + NAREG|NASL, RESC1, + " sll AL,AR,AL ! shift left\n", }, + +{ LS, INAREG, + SAREG, TLONGLONG|TULONGLONG, + SANY, TANY, + NAREG|NASL, RESC1, + " sllx AL,AR,AL ! shift left\n", }, + + +/* Assignments */ + +{ ASSIGN, FOREFF|INAREG, + SOREG, TWORD, + SAREG, TWORD, + 0, RDEST, + " stw AR,[AL] ! store (u)int32\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SOREG, TSHORT|TUSHORT, + SAREG, TSHORT|TUSHORT, + 0, RDEST, + " sth AR,[AL] ! store (u)int16\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SOREG, TCHAR|TUCHAR, + SAREG, TCHAR|TUCHAR, + 0, RDEST, + " stb AR,[AL] ! store (u)int8\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SOREG, TLONGLONG|TULONGLONG|TPOINT, + SAREG, TLONGLONG|TULONGLONG|TPOINT, + 0, RDEST, + " stx AR,[AL] ! store (u)int64\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SNAME, TWORD, + SAREG, TWORD, + NAREG, RDEST, + " sethi %h44(AL),A1 \t! store (u)int32 into sname\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " stw AR,[A1+%l44(AL)]\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SNAME, TSHORT|TUSHORT, + SAREG, TSHORT|TUSHORT, + NAREG, RDEST, + " sethi %h44(AL),A1 \t! store (u)int16 into sname\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " sth AR,[A1+%l44(AL)]\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SNAME, TCHAR|TUCHAR, + SAREG, TCHAR|TUCHAR, + NAREG, RDEST, + " sethi %h44(AL),A1 \t! store (u)int8 into sname\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " stb AR,[A1+%l44(AL)]\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SNAME, TLONGLONG|TULONGLONG|TPOINT, + SAREG, TLONGLONG|TULONGLONG|TPOINT, + NAREG, RDEST, + " sethi %h44(AL),A1 \t! store (u)int64 into sname\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " stx AR,[A1+%l44(AL)]\n" + " nop\n", }, + +{ ASSIGN, FOREFF|INAREG, + SAREG, TANY, + SAREG, TANY, + 0, RDEST, + " mov AL, AR ! register move\n", }, + +/* Comparisons. */ + +{ EQ, FORCC, + SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR, + SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR, + 0, RESCC, + " cmp AL,AR\n" + " be LC\n" + " nop\n", }, + +{ NE, FORCC, + SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR, + SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR, + 0, RESCC, + " cmp AL,AR\n" + " bne LC\n" + " nop\n", }, + +{ OPLOG, FORCC, + SAREG, TANY, + SZERO, TANY, + 0, RESCC, + " O AL,LC\n" + " nop\n", }, +{ OPLOG, FORCC, + SAREG, TANY, + SAREG, TANY, + NAREG|NASL, RESCC, + " sub AL,AR,A1 ! oplog\n" + " O A1,LC\n" + " nop\n", }, +{ OPLOG, FORCC, + SAREG, TANY, + SCCON, TANY, + NAREG|NASL, RESCC, + " sub AL,AR,A1 ! oplog sccon\n" + " O A1,LC\n" + " nop\n", }, + + +/* Load constants to register. */ + +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TLONGLONG|TULONGLONG|TPOINT, + NAREG, RESC1, + " sethi %h44(AL),A1\t ! load const (u)int64 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " ldx [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TWORD, + NAREG, RESC1, + " sethi %h44(AL),A1\t ! load const int32 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " ldsw [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TUWORD, + NAREG, RESC1, + " sethi %h44(AL),A1\t! load const uint32 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " lduw [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TSHORT, + NAREG, RESC1, + " sethi %h44(AL),A1\t! load const int16 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " ldsh [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TUSHORT, + NAREG, RESC1, + " sethi %h44(AL),A1\t ! load const uint16 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " lduh [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TCHAR, + NAREG, RESC1, + " sethi %h44(AL),A1\t\t! load const int8 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " ldsb [A1+%l44(AL)],A1\n", }, +{ OPLTYPE, INAREG, + SCON, TANY, + SNAME, TUCHAR, + NAREG, RESC1, + " sethi %h44(AL),A1\t! load const uint8 to reg\n" + " or A1,%m44(AL),A1\n" + " sllx A1,12,A1\n" + " ldub [A1+%l44(AL)],A1\n", }, + +{ OPLTYPE, INAREG, + SANY, TANY, + SCON, TANY, + NAREG, RESC1, + "ZA" }, + + +/* Convert LTYPE to reg. */ + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TCHAR, + NAREG, RESC1, + " ldsb [AL],A1 ! load int8 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TUCHAR, + NAREG, RESC1, + " ldub [AL],A1 ! load uint8 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TSHORT, + NAREG, RESC1, + " ldsh [AL],A1 ! load int16 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TUSHORT, + NAREG, RESC1, + " lduh [AL],A1 ! load uint16 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TWORD, + NAREG, RESC1, + " ldsw [AL],A1 ! load int32 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TWORD, + NAREG, RESC1, + " lduw [AL],A1 ! load uint32 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SAREG, TANY, + SOREG, TLONGLONG|TULONGLONG|TPOINT, + NAREG, RESC1, + " ldx [AL],A1 ! load (u)int64 to reg\n" + " nop\n", }, + +{ OPLTYPE, INAREG, + SANY, TANY, + SZERO, TANY, + NAREG, RESC1, + " mov \%g0,A1\t ! load 0 to reg\n", }, + + +/* Jumps. */ + +{ GOTO, FOREFF, + SCON, TANY, + SANY, TANY, + 0, RNOP, + " call LL ! goto LL\n" + " nop\n", }, + +{ UCALL, FOREFF, + SCON, TANY, + SANY, TANY, + 0, 0, + " call CL ! void CL()\n" + " nop\n", }, + +{ UCALL, INAREG, + SCON, TANY, + SAREG, TANY, + NAREG, RESC1, + " call CL ! = CL()\n" + " nop\n", }, + +{ CALL, FOREFF, + SCON, TANY, + SANY, TANY, + 0, 0, + " call CL ! void CL(constant)\n" + " nop\n", }, + +{ CALL, INAREG, + SCON, TANY, + SAREG, TANY, + NAREG, RESC1, + " call CL ! = CL(constant)\n" + " nop\n", }, + +{ CALL, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG, RESC1, + " call AL ! = AL(args)\n" + " nop\n", }, + +{ CALL, FOREFF, + SAREG, TANY, + SANY, TANY, + 0, 0, + " call AL ! void AL(args)\n" + " nop\n", }, + +{ UCALL, FOREFF, + SAREG, TANY, + SANY, TANY, + 0, 0, + " call AL ! (*AL)()\n" + " nop\n", }, + +{ UCALL, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG, RESC1, + " call AL ! = (*AL)()\n" + " nop\n", }, + +{ CALL, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG, RESC1, + " call AL ! = (*AL)(args)\n" + " nop\n", }, + + +/* Indirection. */ + +{ OPSIMP, INAREG, + SAREG, TANY, + SAREG, TANY, + NAREG|NASR|NASL, RESC1, + " O AL,AR,A1\n", }, + +{ UMUL, INAREG, + SANY, TLONGLONG|TULONGLONG|TPOINT, + SOREG, TLONGLONG|TULONGLONG|TPOINT, + NAREG, RESC1, + " ldx [AL],A1 ! (u)int64 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TWORD, + SOREG, TWORD, + NAREG, RESC1, + " ldsw [AL],A1 ! int32 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TUWORD, + SOREG, TUWORD, + NAREG, RESC1, + " lduw [AL],A1 ! uint32 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TCHAR, + SOREG, TCHAR, + NAREG, RESC1, + " ldsb [AL],A1 ! int8 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TUCHAR, + SOREG, TUCHAR, + NAREG, RESC1, + " ldub [AL],A1 ! uint8 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TSHORT, + SOREG, TSHORT, + NAREG, RESC1, + " ldsh [AL],A1 ! int16 load\n" + " nop\n", }, +{ UMUL, INAREG, + SANY, TUSHORT, + SOREG, TUSHORT, + NAREG, RESC1, + " lduh [AL],A1 ! uint16 load\n" + " nop\n", }, + +{ FREE,FREE,FREE,FREE,FREE,FREE,FREE,FREE, "ERR: printing free op\n" }, + +}; + +int tablesize = sizeof(table)/sizeof(table[0]); |