summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2007-11-01 10:52:59 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2007-11-01 10:52:59 +0000
commit59110514bbd7cdc9028bf9cc78ac11d6316430a8 (patch)
tree308de9edfd9e2a8a40a3abaecc0c1c3c754d9858
parent9b80eb276466cb5f1c5d221bf0afc9a55c488916 (diff)
Pull from master repo, commit by myself:
next step for ELFABI, hello world works with ELFABI, but register pairs still produce wrong assembly; with Dale Rahn
-rw-r--r--usr.bin/pcc/powerpc/code.c481
-rw-r--r--usr.bin/pcc/powerpc/local.c65
-rw-r--r--usr.bin/pcc/powerpc/local2.c83
-rw-r--r--usr.bin/pcc/powerpc/macdefs.h10
-rw-r--r--usr.bin/pcc/powerpc/order.c37
-rw-r--r--usr.bin/pcc/powerpc/table.c505
6 files changed, 906 insertions, 275 deletions
diff --git a/usr.bin/pcc/powerpc/code.c b/usr.bin/pcc/powerpc/code.c
index 288e9d79f34..cde81183a4d 100644
--- a/usr.bin/pcc/powerpc/code.c
+++ b/usr.bin/pcc/powerpc/code.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: code.c,v 1.1 2007/10/20 10:01:38 otto Exp $ */
+/* $OpenBSD: code.c,v 1.2 2007/11/01 10:52:58 otto Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -27,10 +27,16 @@
*/
#include <assert.h>
+#include <stdlib.h>
-# include "pass1.h"
+#include "pass1.h"
#include "pass2.h"
+static void genswitch_simple(int num, struct swents **p, int n);
+static void genswitch_bintree(int num, struct swents **p, int n);
+static void genswitch_table(int num, struct swents **p, int n);
+static void genswitch_mrst(int num, struct swents **p, int n);
+
/*
* cause the alignment to become a multiple of n
* never called for text segment.
@@ -323,12 +329,34 @@ fldty(struct symtab *p)
void
genswitch(int num, struct swents **p, int n)
{
+ if (n == 0) {
+ if (p[0]->sval != 0)
+ branch(p[0]->sval);
+ return;
+ }
+
+#ifdef PCC_DEBUG
+ if (xdebug) {
+ int i;
+ for (i = 1; i <= n; i++)
+ printf("%d: %llu\n", i, p[i]->sval);
+ }
+#endif
+
+ if (0)
+ genswitch_table(num, p, n);
+ if (0)
+ genswitch_bintree(num, p, n);
+ genswitch_mrst(num, p, n);
+}
+
+static void
+genswitch_simple(int num, struct swents **p, int n)
+{
NODE *r;
int i;
- /* simple switch code */
for (i = 1; i <= n; ++i) {
- /* already in 1 */
r = tempnode(num, INT, 0, MKSUE(INT));
r = buildtree(NE, r, bcon(p[i]->sval));
cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab));
@@ -336,3 +364,448 @@ genswitch(int num, struct swents **p, int n)
if (p[0]->slab > 0)
branch(p[0]->slab);
}
+
+static void bintree_rec(int num, struct swents **p, int n, int s, int e);
+
+static void
+genswitch_bintree(int num, struct swents **p, int n)
+{
+ int lab = getlab();
+
+ if (p[0]->slab == 0)
+ p[0]->slab = lab;
+
+ bintree_rec(num, p, n, 1, n);
+
+ plabel(lab);
+}
+
+static void
+bintree_rec(int num, struct swents **p, int n, int s, int e)
+{
+ NODE *r;
+ int rlabel;
+ int h;
+
+ if (s == e) {
+ r = tempnode(num, INT, 0, MKSUE(INT));
+ r = buildtree(NE, r, bcon(p[s]->sval));
+ cbranch(buildtree(NOT, r, NIL), bcon(p[s]->slab));
+ branch(p[0]->slab);
+ return;
+ }
+
+ rlabel = getlab();
+
+ h = s + (e - s) / 2;
+
+ r = tempnode(num, INT, 0, MKSUE(INT));
+ r = buildtree(GT, r, bcon(p[h]->sval));
+ cbranch(r, bcon(rlabel));
+ bintree_rec(num, p, n, s, h);
+ plabel(rlabel);
+ bintree_rec(num, p, n, h+1, e);
+}
+
+
+
+static void
+genswitch_table(int num, struct swents **p, int n)
+{
+ NODE *r, *t;
+ int tval;
+ int minval, maxval, range;
+ int deflabel, tbllabel;
+ int i, j;
+
+ minval = p[1]->sval;
+ maxval = p[n]->sval;
+
+ range = maxval - minval + 1;
+
+ if (n < 10 || range > 3 * n) {
+ /* too small or too sparse for jump table */
+ genswitch_simple(num, p, n);
+ return;
+ }
+
+ r = tempnode(num, UNSIGNED, 0, MKSUE(UNSIGNED));
+ r = buildtree(MINUS, r, bcon(minval));
+ t = tempnode(0, UNSIGNED, 0, MKSUE(UNSIGNED));
+ tval = t->n_lval;
+ r = buildtree(ASSIGN, t, r);
+ ecomp(r);
+
+ deflabel = p[0]->slab;
+ if (deflabel == 0)
+ deflabel = getlab();
+
+ t = tempnode(tval, UNSIGNED, 0, MKSUE(UNSIGNED));
+ cbranch(buildtree(GT, t, bcon(maxval-minval)), bcon(deflabel));
+
+ tbllabel = getlab();
+ struct symtab *strtbl = lookup("__switch_table", SLBLNAME|STEMP);
+ strtbl->soffset = tbllabel;
+ strtbl->sclass = ILABEL;
+ strtbl->stype = INCREF(UCHAR);
+
+ t = block(NAME, NIL, NIL, UNSIGNED, 0, MKSUE(UNSIGNED));
+ t->n_sp = strtbl;
+ t = buildtree(ADDROF, t, NIL);
+ r = tempnode(tval, UNSIGNED, 0, MKSUE(INT));
+ r = buildtree(PLUS, t, r);
+ t = tempnode(0, INCREF(UNSIGNED), 0, MKSUE(UNSIGNED));
+ r = buildtree(ASSIGN, t, r);
+ ecomp(r);
+
+ r = tempnode(t->n_lval, INCREF(UNSIGNED), 0, MKSUE(UNSIGNED));
+ r = buildtree(UMUL, r, NIL);
+ t = block(NAME, NIL, NIL, UCHAR, 0, MKSUE(UCHAR));
+ t->n_sp = strtbl;
+ t = buildtree(ADDROF, t, NIL);
+ r = buildtree(PLUS, t, r);
+ r = block(GOTO, r, NIL, 0, 0, 0);
+ ecomp(r);
+
+ plabel(tbllabel);
+ for (i = minval, j=1; i <= maxval; i++) {
+ char *entry = tmpalloc(20);
+ int lab = deflabel;
+ //printf("; minval=%d, maxval=%d, i=%d, j=%d p[j]=%lld\n", minval, maxval, i, j, p[j]->sval);
+ if (p[j]->sval == i) {
+ lab = p[j]->slab;
+ j++;
+ }
+ snprintf(entry, 20, ".long " LABFMT "-" LABFMT, lab, tbllabel);
+ send_passt(IP_ASM, entry);
+ }
+
+ if (p[0]->slab <= 0)
+ plabel(deflabel);
+}
+
+#define DPRINTF(x) if (xdebug) printf x
+//#define DPRINTF(x) do { } while(0)
+
+#define MIN_TABLE_SIZE 8
+
+/*
+ * Multi-way Radix Search Tree (MRST)
+ */
+
+static void mrst_rec(int num, struct swents **p, int n, int *state, int lab);
+static unsigned long mrst_find_window(struct swents **p, int n, int *state, int lab, int *len, int *lowbit);
+void mrst_put_entry_and_recurse(int num, struct swents **p, int n, int *state, int tbllabel, int lab, unsigned long j, unsigned long tblsize, unsigned long Wmax, int lowbit);
+
+static void
+genswitch_mrst(int num, struct swents **p, int n)
+{
+ int *state;
+ int i;
+ int putlabel = 0;
+
+ if (n < 10) {
+ /* too small for MRST */
+ genswitch_simple(num, p, n);
+ return;
+ }
+
+ state = tmpalloc((n+1)*sizeof(int));
+ for (i = 0; i <= n; i++)
+ state[i] = 0;
+
+ if (p[0]->slab == 0) {
+ p[0]->slab = getlab();
+ putlabel = 1;
+ }
+
+ mrst_rec(num, p, n, state, 0);
+
+ if (putlabel)
+ plabel(p[0]->slab);
+}
+
+
+/*
+ * Look through the cases and generate a table or
+ * list of simple comparisons. If generating a table,
+ * invoke mrst_put_entry_and_recurse() to put
+ * an entry in the table and recurse.
+ */
+static void
+mrst_rec(int num, struct swents **p, int n, int *state, int lab)
+{
+ int len, lowbit;
+ unsigned long Wmax;
+ unsigned int tblsize;
+ NODE *t;
+ NODE *r;
+ int tval;
+ int i;
+
+ DPRINTF(("mrst_rec: num=%d, n=%d, lab=%d\n", num, n, lab));
+
+ /* find best window to cover set*/
+ Wmax = mrst_find_window(p, n, state, lab, &len, &lowbit);
+ tblsize = (1 << len);
+ assert(len > 0 && tblsize > 0);
+
+ DPRINTF(("mrst_rec: Wmax=%lu, lowbit=%d, tblsize=%u\n",
+ Wmax, lowbit, tblsize));
+
+ if (lab)
+ plabel(lab);
+
+ if (tblsize <= MIN_TABLE_SIZE) {
+ DPRINTF(("msrt_rec: break the recursion\n"));
+ for (i = 1; i <= n; i++) {
+ if (state[i] == lab) {
+ t = tempnode(num, UNSIGNED, 0, MKSUE(UNSIGNED));
+ cbranch(buildtree(EQ, t, bcon(p[i]->sval)),
+ bcon(p[i]->slab));
+ }
+ }
+ branch(p[0]->slab);
+ return;
+ }
+
+ DPRINTF(("generating table with %d elements\n", tblsize));
+
+ // AND with Wmax
+ t = tempnode(num, UNSIGNED, 0, MKSUE(UNSIGNED));
+ r = buildtree(AND, t, bcon(Wmax));
+
+ // RS lowbits
+ r = buildtree(RS, r, bcon(lowbit));
+
+ t = tempnode(0, UNSIGNED, 0, MKSUE(UNSIGNED));
+ tval = t->n_lval;
+ r = buildtree(ASSIGN, t, r);
+ ecomp(r);
+
+ int tbllabel = getlab();
+ struct symtab *strtbl = lookup("__switch_table", SLBLNAME|STEMP);
+ strtbl->soffset = tbllabel;
+ strtbl->sclass = ILABEL;
+ strtbl->stype = INCREF(UCHAR);
+
+ t = block(NAME, NIL, NIL, UNSIGNED, 0, MKSUE(UNSIGNED));
+ t->n_sp = strtbl;
+ t = buildtree(ADDROF, t, NIL);
+ r = tempnode(tval, UNSIGNED, 0, MKSUE(INT));
+ r = buildtree(PLUS, t, r);
+ t = tempnode(0, INCREF(UNSIGNED), 0, MKSUE(UNSIGNED));
+ r = buildtree(ASSIGN, t, r);
+ ecomp(r);
+
+ r = tempnode(t->n_lval, INCREF(UNSIGNED), 0, MKSUE(UNSIGNED));
+ r = buildtree(UMUL, r, NIL);
+ t = block(NAME, NIL, NIL, UCHAR, 0, MKSUE(UCHAR));
+ t->n_sp = strtbl;
+ t = buildtree(ADDROF, t, NIL);
+ r = buildtree(PLUS, t, r);
+ r = block(GOTO, r, NIL, 0, 0, 0);
+ ecomp(r);
+
+ plabel(tbllabel);
+
+ mrst_put_entry_and_recurse(num, p, n, state, tbllabel, lab,
+ 0, tblsize, Wmax, lowbit);
+}
+
+
+/*
+ * Put an entry into the table and recurse to the next entry
+ * in the table. On the way back through the recursion, invoke
+ * mrst_rec() to check to see if we should generate another
+ * table.
+ */
+void
+mrst_put_entry_and_recurse(int num, struct swents **p, int n, int *state,
+ int tbllabel, int labval,
+ unsigned long j, unsigned long tblsize, unsigned long Wmax, int lowbit)
+{
+ int i;
+ int found = 0;
+ int lab = getlab();
+
+ /*
+ * Look for labels which map to this table entry.
+ * Mark each one in "state" that they fall inside this table.
+ */
+ for (i = 1; i <= n; i++) {
+ unsigned int val = (p[i]->sval & Wmax) >> lowbit;
+ if (val == j && state[i] == labval) {
+ found = 1;
+ state[i] = lab;
+ }
+ }
+
+ /* couldn't find any labels? goto the default label */
+ if (!found)
+ lab = p[0]->slab;
+
+ /* generate the table entry */
+ char *entry = tmpalloc(20);
+ snprintf(entry, 20, ".long " LABFMT "-" LABFMT, lab, tbllabel);
+ send_passt(IP_ASM, entry);
+
+ DPRINTF(("mrst_put_entry: table=%d, pos=%lu/%lu, label=%d\n",
+ tbllabel, j, tblsize, lab));
+
+ /* go to the next table entry */
+ if (j+1 < tblsize) {
+ mrst_put_entry_and_recurse(num, p, n, state, tbllabel, labval,
+ j+1, tblsize, Wmax, lowbit);
+ }
+
+ /* if we are going to the default label, bail now */
+ if (!found)
+ return;
+
+#ifdef PCC_DEBUG
+ if (xdebug) {
+ printf("state: ");
+ for (i = 1; i <= n; i++)
+ printf("%d ", state[i]);
+ printf("\n");
+ }
+#endif
+
+ /* build another table */
+ mrst_rec(num, p, n, state, lab);
+}
+
+/*
+ * counts the number of entries in a table of size (1 << L) which would
+ * be used given the cases and the mask (W, lowbit).
+ */
+static unsigned int
+mrst_cardinality(struct swents **p, int n, int *state, int step, unsigned long W, int L, int lowbit)
+{
+ unsigned int count = 0;
+ int i;
+
+ if (W == 0)
+ return 0;
+
+ int *vals = (int *)calloc(1 << L, sizeof(int));
+ assert(vals);
+
+ DPRINTF(("mrst_cardinality: "));
+ for (i = 1; i <= n; i++) {
+ int idx;
+ if (state[i] != step)
+ continue;
+ idx = (p[i]->sval & W) >> lowbit;
+ DPRINTF(("%llu->%d, ", p[i]->sval, idx));
+ if (!vals[idx]) {
+ count++;
+ }
+ vals[idx] = 1;
+ }
+ DPRINTF((": found %d entries\n", count));
+ free(vals);
+
+ return count;
+}
+
+/*
+ * Find the maximum window (table size) which would best cover
+ * the set of labels. Algorithm explained in:
+ *
+ * Ulfar Erlingsson, Mukkai Krishnamoorthy and T.V. Raman.
+ * Efficient Multiway Radix Search Trees.
+ * Information Processing Letters 60:3 115-120 (November 1996)
+ */
+
+static unsigned long
+mrst_find_window(struct swents **p, int n, int *state, int lab, int *len, int *lowbit)
+{
+ unsigned int tblsize;
+ unsigned long W = 0;
+ unsigned long Wmax = 0;
+ unsigned long Wleft = (1 << (SZLONG-1));
+ unsigned int C = 0;
+ unsigned int Cmax = 0;
+ int L = 0;
+ int Lmax = 0;
+ int lowmax = 0;
+ int no_b = SZLONG-1;
+ unsigned long b = (1 << (SZLONG-1));
+
+ DPRINTF(("mrst_find_window: n=%d, lab=%d\n", n, lab));
+
+ for (; b > 0; b >>= 1, no_b--) {
+
+ // select the next bit
+ W |= b;
+ L += 1;
+
+ tblsize = 1 << L;
+ assert(tblsize > 0);
+
+ DPRINTF(("no_b=%d, b=0x%lx, Wleft=0x%lx, W=0x%lx, Wmax=0x%lx, L=%d, Lmax=%d, Cmax=%u, lowmax=%d, tblsize=%u\n", no_b, b, Wleft, W, Wmax, L, Lmax, Cmax, lowmax, tblsize));
+
+ C = mrst_cardinality(p, n, state, lab, W, L, no_b);
+ DPRINTF((" -> cardinality is %d\n", C));
+
+ if (2*C >= tblsize) {
+ DPRINTF(("(found good match, keep adding to table)\n"));
+ Wmax = W;
+ Lmax = L;
+ lowmax = no_b;
+ Cmax = C;
+ } else {
+ DPRINTF(("(too sparse)\n"));
+ assert((W & Wleft) != 0);
+
+ /* flip the MSB and see if we get a better match */
+ W ^= Wleft;
+ Wleft >>= 1;
+ L -= 1;
+
+ DPRINTF((" --> trying W=0x%lx and L=%d and Cmax=%u\n", W, L, Cmax));
+ C = mrst_cardinality(p, n, state, lab, W, L, no_b);
+ DPRINTF((" --> C=%u\n", C));
+ if (C > Cmax) {
+ Wmax = W;
+ Lmax = L;
+ lowmax = no_b;
+ Cmax = C;
+ DPRINTF((" --> better!\n"));
+ } else {
+ DPRINTF((" --> no better\n"));
+ }
+ }
+
+ }
+
+#ifdef PCC_DEBUG
+ if (xdebug) {
+ int i;
+ int hibit = lowmax + Lmax;
+ printf("msrt_find_window: Wmax=0x%lx, lowbit=%d, result=", Wmax, lowmax);
+ for (i = 31; i >= 0; i--) {
+ int mask = (1 << i);
+ if (i == hibit)
+ printf("[");
+ if (Wmax & mask)
+ printf("1");
+ else
+ printf("0");
+ if (i == lowmax)
+ printf("]");
+ }
+ printf("\n");
+ }
+#endif
+
+ assert(Lmax > 0);
+ *len = Lmax;
+ *lowbit = lowmax;
+
+ DPRINTF(("msrt_find_window: returning Wmax=%lu, len=%d, lowbit=%d [tblsize=%u, entries=%u]\n", Wmax, Lmax, lowmax, tblsize, C));
+
+ return Wmax;
+}
diff --git a/usr.bin/pcc/powerpc/local.c b/usr.bin/pcc/powerpc/local.c
index 7b921f24dc5..ad596384cf7 100644
--- a/usr.bin/pcc/powerpc/local.c
+++ b/usr.bin/pcc/powerpc/local.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local.c,v 1.2 2007/10/21 17:41:06 otto Exp $ */
+/* $OpenBSD: local.c,v 1.3 2007/11/01 10:52:58 otto Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -90,6 +90,10 @@ fixupfuncargs(NODE *r, int *reg)
/* recurse to the bottom of the tree */
fixupfuncargs(r->n_left, reg);
+ if (r->n_right->n_op == STARG) {
+ assert(0);
+ }
+
r->n_right = block(ASSIGN, NIL, r->n_right,
r->n_right->n_type, r->n_right->n_df,
r->n_right->n_sue);
@@ -104,6 +108,17 @@ fixupfuncargs(NODE *r, int *reg)
}
} else {
+
+ if (r->n_op == STARG) {
+ assert(0);
+#if 0
+ copystructtostack(r->);
+ *r = *(r->n_left)
+ nfree(r->n_left);
+ return;
+#endif
+ }
+
NODE *l = talloc();
*l = *r;
r->n_op = ASSIGN;
@@ -157,23 +172,33 @@ clocal(NODE *p)
}
#endif
- if (kflag && p->n_left->n_op == NAME) {
+ if (kflag && blevel > 0 && p->n_left->n_op == NAME) {
+
+#if 0
+ printf("sclass=%d, squal=%d, slevel=%d: ", p->n_left->n_sp->sclass, p->n_left->n_sp->squal, p->n_left->n_sp->slevel);
+ tprint(stdout, p->n_left->n_type, p->n_left->n_qual);
+ printf("\n");
+#endif
TWORD t = DECREF(p->n_type);
if (!ISFTN(t)) {
r = talloc();
*r = *p;
-
+#if 1
+ /* cast to pointer-to-char before adding offset */
l = block(REG, NIL, NIL, INT, p->n_df, p->n_sue);
l->n_lval = 0;
l->n_rval = R31;
- p->n_op = PLUS;
+ r = block(SCONV, r, NIL, INCREF(UCHAR), p->n_df,p->n_sue);
+ r = block(PLUS, l, r, r->n_type, r->n_df, r->n_sue);
+ p->n_op = SCONV;
p->n_lval = 0;
- p->n_left = l;
+ p->n_left = r;
p->n_rval = 0;
- p->n_right = r;
+ p->n_right = 0;
+#endif
}
}
@@ -195,23 +220,21 @@ clocal(NODE *p)
p = stref(block(STREF, r, p, 0, 0, 0));
break;
- case STATIC:
- if (q->slevel == 0)
- break;
- p->n_lval = 0;
- p->n_sp = q;
- break;
-
case REGISTER:
p->n_op = REG;
p->n_lval = 0;
p->n_rval = q->soffset;
break;
+ case STATIC:
+ if (q->slevel > 0) {
+ p->n_lval = 0;
+ p->n_sp = q;
+ }
+ /* FALLTHROUGH */
#if 1
default:
- if (kflag && !ISFTN(p->n_type)) {
-
+ if (kflag && blevel > 0 && !ISFTN(p->n_type)) {
TWORD t = p->n_type;
l = block(REG, NIL, NIL, INCREF(t), p->n_df, p->n_sue);
l->n_lval = 0;
@@ -792,7 +815,7 @@ finval(NODE *p)
char *
exname(char *p)
{
-#if 0
+#ifndef ELFABI
#define NCHNAM 256
static char text[NCHNAM+1];
int i;
@@ -806,8 +829,11 @@ exname(char *p)
text[i] = '\0';
text[NCHNAM] = '\0'; /* truncate */
+
+ return (text);
+#else
+ return (p == NULL ? "" : p);
#endif
- return (p);
}
/*
@@ -888,7 +914,12 @@ deflab1(int label)
printf(LABFMT ":\n", label);
}
+#ifdef ELFABI
+static char *loctbl[] = { "text", "data", "section .rodata,",
+ "section .rodata" };
+#else
static char *loctbl[] = { "text", "data", "section .rodata,", "cstring" };
+#endif
void
setloc1(int locc)
diff --git a/usr.bin/pcc/powerpc/local2.c b/usr.bin/pcc/powerpc/local2.c
index 77d1001a248..748226f6942 100644
--- a/usr.bin/pcc/powerpc/local2.c
+++ b/usr.bin/pcc/powerpc/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.1 2007/10/20 10:01:38 otto Exp $ */
+/* $OpenBSD: local2.c,v 1.2 2007/11/01 10:52:58 otto Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -57,13 +57,6 @@ addstub(struct stub *list, char *name)
}
void
-lineid(int l, char *fn)
-{
- /* identify line l and file fn */
- printf("# line %d, file %s\n", l, fn);
-}
-
-void
deflab(int label)
{
printf(LABFMT ":\n", label);
@@ -88,11 +81,11 @@ prtprolog(struct interpass_prolog *ipp, int addto)
// get return address (not required for leaf function)
printf(" mflr %s\n", rnames[R0]);
// save registers R30 and R31
- printf(" stmw %s, -8(%s)\n", rnames[R30], rnames[R1]);
+ printf(" stmw %s,-8(%s)\n", rnames[R30], rnames[R1]);
// save return address (not required for leaf function)
- printf(" stw %s, 8(%s)\n", rnames[R0], rnames[R1]);
+ printf(" stw %s,8(%s)\n", rnames[R0], rnames[R1]);
// create the new stack frame
- printf(" stwu %s, -%d(%s)\n", rnames[R1], addto, rnames[R1]);
+ printf(" stwu %s,-%d(%s)\n", rnames[R1], addto, rnames[R1]);
if (kflag) {
funcname = ipp->ipp_name;
@@ -200,7 +193,7 @@ eoftn(struct interpass_prolog *ipp)
/* return from function code */
for (i = ipp->ipp_regs, j = 0; i ; i >>= 1, j++) {
if (i & 1)
- printf(" lwz %s, %d(%s)\n",
+ printf("\tlwz %s,%d(%s)\n",
rnames[j], regoff[j], rnames[FPREG]);
}
@@ -215,11 +208,11 @@ eoftn(struct interpass_prolog *ipp)
printf(" ret $4\n");
} else {
// unwind stack frame
- printf(" lwz %s,0(%s)\n", rnames[R1], rnames[R1]);
- printf(" lwz %s,8(%s)\n", rnames[R0], rnames[R1]);
- printf(" mtlr %s\n", rnames[R0]);
- printf(" lmw %s,-8(%s)\n", rnames[R30], rnames[R1]);
- printf(" blr\n");
+ printf("\tlwz %s,0(%s)\n", rnames[R1], rnames[R1]);
+ printf("\tlwz %s,8(%s)\n", rnames[R0], rnames[R1]);
+ printf("\tmtlr %s\n", rnames[R0]);
+ printf("\tlmw %s,-8(%s)\n", rnames[R30], rnames[R1]);
+ printf("\tblr\n");
}
}
@@ -260,7 +253,7 @@ hopcode(int f, int o)
* Return type size in bytes. Used by R2REGS, arg 2 to offset().
*/
int
-tlen(p) NODE *p;
+tlen(NODE *p)
{
switch(p->n_type) {
case CHAR:
@@ -758,24 +751,21 @@ conput(FILE *fp, NODE *p)
switch (p->n_op) {
case ICON:
#if 0
- printf("XXX type = %x\n", p->n_type);
-#endif
- if (p->n_sp != NULL &&
-#if 0
- (p->n_sp->sclass != STATIC) &&
+ if (p->n_sp)
+ printf(" [class=%d,level=%d] ", p->n_sp->sclass, p->n_sp->slevel);
#endif
- (p->n_sp->sclass != ILABEL))
- s = exname(p->n_name);
- else
+ if (p->n_sp == NULL || (p->n_sp->sclass == ILABEL ||
+ (p->n_sp->sclass == STATIC && p->n_sp->slevel > 0)))
s = p->n_name;
+ else
+ s = exname(p->n_name);
if (*s != '\0') {
if (kflag && p->n_sp && ISFTN(p->n_sp->stype)) {
fprintf(fp, "%s$stub", s);
addstub(&stublist, s);
- } else if (kflag && p->n_sp) {
-// printf("sclass=%x sflags=%x\n", p->n_sp->sclass, p->n_sp->sflags);
- if (p->n_sp && (p->n_sp->sclass != STATIC && p->n_sp->sflags != SSTRING)) {
+ } else if (kflag) {
+ if (p->n_sp && p->n_sp->sclass == EXTERN) {
fprintf(fp, "L%s$non_lazy_ptr", s);
addstub(&nlplist, s);
} else {
@@ -850,15 +840,19 @@ adrput(FILE *io, NODE *p)
case NAME:
if (p->n_name[0] != '\0') {
- if (kflag && p->n_sp && (p->n_sp->sclass == STATIC || p->n_sp->sflags != SSTRING)) {
+ if (kflag && p->n_sp && (p->n_sp->sclass == EXTERN || p->n_sp->sclass == EXTDEF)) {
fprintf(io, "L%s$non_lazy_ptr", exname(p->n_name));
addstub(&nlplist, exname(p->n_name));
fprintf(io, "-L%s$pb", exname(funcname));
- } else if (kflag) {
+ } else if (kflag && p->n_sp && p->n_sp->sclass == STATIC && p->n_sp->slevel == 0) {
fprintf(io, "%s", exname(p->n_name));
fprintf(io, "-L%s$pb", exname(funcname));
- } else
- fputs(exname(p->n_name), io);
+ } else if (kflag && p->n_sp && (p->n_sp->sclass == ILABEL || (p->n_sp->sclass == STATIC && p->n_sp->sclass > 0))) {
+ fprintf(io, "%s", p->n_name);
+ fprintf(io, "-L%s$pb", exname(funcname));
+ } else {
+ fputs(p->n_name, io);
+ }
if (p->n_lval != 0)
fprintf(io, "+" CONFMT, p->n_lval);
} else
@@ -927,7 +921,7 @@ cbgen(int o, int lab)
{
if (o < EQ || o > UGT)
comperr("bad conditional branch: %s", opst[o]);
- printf(" %s " LABFMT "\n", ccbranches[o-EQ], lab);
+ printf("\t%s " LABFMT "\n", ccbranches[o-EQ], lab);
}
static void
@@ -1150,6 +1144,19 @@ COLORMAP(int c, int *r)
#endif
}
+#ifdef ELFABI
+char *rnames[] = {
+ "%r0", "%r1", "%r2", "%r3","%r4","%r5", "%r6", "%r7", "%r8",
+ "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "%r16",
+ "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23", "%r24",
+ "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
+ /* the order is flipped, because we are big endian */
+ "%r4\0%r3\0", "%r5\0%r4\0", "%r6\0%r5\0", "%r7\0%r6\0",
+ "%r8\0%r7\0", "%r9\0%r8\0", "%r10%r9\0", "%r15%r14", "%r17%r16",
+ "%r19%r18", "%r21%r20", "%r23%r22", "%r25%r24", "%r27%r26",
+ "%r29%r28", "%r31%r30",
+};
+#else
char *rnames[] = {
"r0", "r1", "r2", "r3","r4","r5", "r6", "r7", "r8",
"r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16",
@@ -1161,6 +1168,7 @@ char *rnames[] = {
"r19r18", "r21r20", "r23r22", "r25r24", "r27r26",
"r29r28", "r31r30",
};
+#endif
/*
* Return a class suitable for a specific type.
@@ -1209,11 +1217,10 @@ special(NODE *p, int shape)
if (o == STCALL || o == USTCALL)
return SRREG;
break;
-#if 0
- case SSYMBOL:
- if (p->n_op == NAME && !kflag)
+ case SPCON:
+ if (o == ICON && p->n_name[0] == 0 && (p->n_lval & ~0xffff) == 0)
return SRDIR;
-#endif
+ break;
}
return SRNOPE;
}
diff --git a/usr.bin/pcc/powerpc/macdefs.h b/usr.bin/pcc/powerpc/macdefs.h
index 3f58fb9604d..4e4406428a6 100644
--- a/usr.bin/pcc/powerpc/macdefs.h
+++ b/usr.bin/pcc/powerpc/macdefs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: macdefs.h,v 1.1 2007/10/20 10:01:38 otto Exp $ */
+/* $OpenBSD: macdefs.h,v 1.2 2007/11/01 10:52:58 otto Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -89,6 +89,8 @@
#define BOOL_TYPE INT /* what used to store _Bool */
#define WCHAR_TYPE INT /* what used to store wchar_t */
+#define ELFABI
+
/*
* Use large-enough types.
*/
@@ -97,8 +99,13 @@ typedef unsigned long long U_CONSZ;
typedef long long OFFSZ;
#define CONFMT "%lld" /* format for printing constants */
+#ifdef ELFABI
+#define LABFMT ".L%d" /* format for printing labels */
+#else
#define LABFMT "L%d" /* format for printing labels */
+#endif
#define STABLBL "LL%d" /* format for stab (debugging) labels */
+#define STAB_LINE_ABSOLUTE /* S_LINE fields use absolute addresses */
#define MYP2TREE(p) myp2tree(p);
@@ -261,6 +268,7 @@ int COLORMAP(int c, int *r);
#define SHSTR (MAXSPECIAL+1) /* short struct */
#define SFUNCALL (MAXSPECIAL+2) /* struct assign after function call */
+#define SPCON (MAXSPECIAL+3) /* positive constant */
struct stub {
struct { struct stub *q_forw, *q_back; } link;
diff --git a/usr.bin/pcc/powerpc/order.c b/usr.bin/pcc/powerpc/order.c
index 215a2a3f20c..abc6085248b 100644
--- a/usr.bin/pcc/powerpc/order.c
+++ b/usr.bin/pcc/powerpc/order.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: order.c,v 1.1 2007/10/20 10:01:38 otto Exp $ */
+/* $OpenBSD: order.c,v 1.2 2007/11/01 10:52:58 otto Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -40,7 +40,7 @@ int canaddr(NODE *);
int
notoff(TWORD t, int r, CONSZ off, char *cp)
{
-// if (cp) return 1;
+ if (cp && cp[0]) return 1;
return !(off < 32768 && off > -32769); /* YES */
}
@@ -67,6 +67,7 @@ offstar(NODE *p, int shape)
/* Converted in ormake() */
return;
}
+ /* usually for arraying indexing: */
if (r->n_op == LS && r->n_right->n_op == ICON &&
r->n_right->n_lval == 2 && p->n_op == PLUS) {
if (isreg(p->n_left) == 0)
@@ -85,15 +86,40 @@ offstar(NODE *p, int shape)
void
myormake(NODE *q)
{
-#if 0
- NODE *p;
+#if 1
+ NODE *p, *r;
#endif
if (x2debug)
printf("myormake(%p)\n", q);
-#if 0
+#if 1
p = q->n_left;
+ if (q->n_op != OREG && p->n_op == REG) {
+ q->n_op = OREG;
+ q->n_lval = 0;
+ q->n_rval = p->n_rval;
+ tfree(p);
+ return;
+ }
+#endif
+
+#if 1
+ /* usually for array indexing */
+ p = q->n_left;
+ if (p->n_op == PLUS && (r = p->n_right)->n_op == LS &&
+ r->n_right->n_op == ICON && r->n_right->n_lval == 2 &&
+ p->n_left->n_op == REG && r->n_left->n_op == REG) {
+ if (isreg(p->n_left) == 0)
+ (void)geninsn(p->n_left, INAREG);
+ q->n_op = OREG;
+ q->n_lval = 0;
+ q->n_rval = p->n_left->n_rval;
+ tfree(p);
+ }
+#endif
+
+#if 0
if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_right->n_op == ICON) {
if (isreg(p->n_left) == 0)
(void)geninsn(p->n_left, INAREG);
@@ -107,6 +133,7 @@ myormake(NODE *q)
tfree(p);
}
#endif
+ (void)geninsn(p, INAREG);
}
/*
diff --git a/usr.bin/pcc/powerpc/table.c b/usr.bin/pcc/powerpc/table.c
index 07d7418b344..d1696efa1ce 100644
--- a/usr.bin/pcc/powerpc/table.c
+++ b/usr.bin/pcc/powerpc/table.c
@@ -1,5 +1,6 @@
-/*
- * $OpenBSD: table.c,v 1.2 2007/10/21 17:45:44 otto Exp $
+/*-
+ * $OpenBSD: table.c,v 1.3 2007/11/01 10:52:58 otto Exp $
+ *
* Copyright (c) 2007 Gregory McGarry <g.mcgarry@ieee.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +33,16 @@
#define TSWORD TINT|TLONG
#define TWORD TUWORD|TSWORD
+#ifdef ELFABI
+#define HA16(x) # x "@ha"
+#define LO16(x) # x "@l"
+#define COM " # "
+#else
+#define HA16(x) "ha16(" # x ")"
+#define LO16(x) "lo16(" # x ")"
+#define COM " ; "
+#endif
+
struct optab table[] = {
/* First entry must be an empty entry */
{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
@@ -41,7 +52,7 @@ struct optab table[] = {
SAREG, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
0, RLEFT,
- " # pointer conversion", },
+ COM "pointer conversion\n", },
/*
* Conversions of integral types
@@ -52,28 +63,35 @@ struct optab table[] = {
INAREG, TCHAR|TUCHAR,
INAREG, TCHAR|TUCHAR,
0, RLEFT,
- " # convert a between (u)uchar and (u)char\n", },
+ COM "convert between (u)char and (u)char\n", },
+
+/* convert (u)short to (u)short */
+{ SCONV, INAREG,
+ INAREG, TSHORT|TUSHORT,
+ INAREG, TSHORT|TUSHORT,
+ 0, RLEFT,
+ COM "convert between (u)short and (u)short\n", },
/* convert pointers to (u)int/(u)long */
{ SCONV, INAREG,
SAREG, TPOINT|TWORD,
SAREG, TWORD,
0, RLEFT,
- " # convert a pointer/word to an int\n", },
+ COM "convert a pointer/word to an int\n", },
/* convert pointers to pointers */
{ SCONV, INAREG,
SAREG, TPOINT,
SAREG, TPOINT,
0, RLEFT,
- " # convert pointers\n", },
+ COM "convert pointers\n", },
/* convert (u)longlong to (u)longlong */
{ SCONV, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, RLEFT,
- " # convert (u)longlong to (u)longlong\n", },
+ COM "convert (u)longlong to (u)longlong\n", },
/* convert char to short */
@@ -81,56 +99,36 @@ struct optab table[] = {
SAREG, TCHAR,
SAREG, TSHORT|TSWORD,
NASL|NAREG, RESC1,
- " extsb A1,AL # convert char to short/int\n", },
+ " extsb A1,AL" COM "convert char to short/int\n", },
/* convert uchar to short */
{ SCONV, INAREG,
SAREG, TUCHAR,
SAREG, TSHORT|TSWORD,
NASL|NAREG, RESC1,
- " # convert uchar to short/int\n", },
+ COM "convert uchar to short/int\n", },
-#if 0
-/* convert char to short in memory */
+/* convert uchar to ushort/uint/ulong */
{ SCONV, INAREG,
- SOREG, TCHAR,
- SAREG, TSHORT|TSWORD,
- NASL|NAREG|NSPECIAL, RESC1,
- " lbz A1,AL # convert char to short/int\n"
- " extsb A1,A1\n", },
-#endif
-
-/* convert (u)char to ushort/uint/ulong */
-{ SCONV, INAREG,
- SAREG, TCHAR|TUCHAR,
+ SAREG, TUCHAR,
SAREG, TUSHORT|TUWORD,
- NASL|NAREG|NSPECIAL, RESC1,
- " andi. A1,AL,255 # convert (u)char (AL) to ushort/unsigned (A1)\n", },
+ 0, RLEFT,
+ COM "convert uchar (AL) to ushort/unsigned (A1)\n", },
-#if 0
-/* convert uchar to short/int/long in memory */
+/* XXX is this necessary? */
+/* convert char to ushort/uint/ulong */
{ SCONV, INAREG,
- SOREG, TUCHAR,
- SAREG, TSHORT|TSWORD,
+ SAREG, TCHAR,
+ SAREG, TUSHORT|TUWORD,
NASL|NAREG|NSPECIAL, RESC1,
- " lbz A1,AL # convert uchar to short/int\n", },
-#endif
-
-#if 0
-/* convert (u)char to ushort/uint/ulong in memory */
-{ SCONV, INAREG,
- SOREG, TCHAR|TUCHAR,
- SAREG, TUSHORT|TUWORD|TULONG,
- NASL|NAREG, RESC1,
- " lbz A1,AL # convert (u)char to ushort/unsigned/ulong\n", },
-#endif
+ " andi. A1,AL,255" COM "convert char (AL) to ushort/unsigned (A1)\n", },
/* convert uchar/ushort/uint to (u)longlong */
{ SCONV, INBREG,
SAREG, TUCHAR|TUSHORT|TUNSIGNED,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " mr A1,AL # convert uchar/ushort/uint to (u)longlong\n"
+ " mr A1,AL" COM "convert uchar/ushort/uint to (u)longlong\n"
" li U1,0\n", },
/* convert char/short/int to ulonglong */
@@ -138,7 +136,7 @@ struct optab table[] = {
SAREG, TCHAR|TSHORT|TSWORD,
SBREG, TULONGLONG,
NBREG, RESC1,
- " mr A1,AL # convert char/short/int to ulonglong\n"
+ " andi. A1,AL,255" COM "convert char/short/int to ulonglong\n"
" li U1,0\n", },
/* convert char/short/int to longlong */
@@ -146,7 +144,7 @@ struct optab table[] = {
SAREG, TCHAR|TSHORT|TSWORD,
SBREG, TLONGLONG,
NBREG|NBSL, RESC1,
- " mr A1,AL # convert char/short/int to longlong\n"
+ " mr A1,AL" COM "convert char/short/int to longlong\n"
" srawi U1,AL,31\n", },
/* convert (u)short to (u)char */
@@ -154,60 +152,60 @@ struct optab table[] = {
SAREG, TSHORT|TUSHORT,
SAREG, TCHAR|TUCHAR,
NSPECIAL|NAREG|NASL, RESC1,
- " andi. A1,AL,255 # convert (u)short to (u)char\n", },
-
-#if 0
-/* convert (u)short to (u)char */
-{ SCONV, INAREG,
- SOREG, TSHORT|TUSHORT,
- SAREG, TCHAR|TUCHAR,
- NSPECIAL|NAREG|NASL, RESC1,
- " lbz A1,AL # convert (u)short to (u)char\n", },
-#endif
+ " andi. A1,AL,255" COM "convert (u)short to (u)char\n", },
+/* XXX is this really necessary? */
/* convert short to int */
{ SCONV, INAREG,
SAREG, TSHORT,
SAREG, TWORD,
NAREG|NASL|NSPECIAL, RESC1,
- " andi. A1,AL,63356 # convert short to int\n", },
-
-#if 0
-/* convert (u)short to uint int memory */
-{ SCONV, INAREG,
- SOREG, TUSHORT|TSHORT,
- SAREG, TWORD,
- NAREG|NASL|NSPECIAL, RESC1,
- " lha A1,AL # convert (u)short to int\n", },
-#endif
+ " andi. A1,AL,65535" COM "convert short to int\n", },
/* convert ushort to (u)int. */
{ SCONV, INAREG,
SAREG, TUSHORT,
SAREG, TWORD,
NASL|NAREG|NSPECIAL, RESC1,
- " andi. A1,AL,65535 # convert ushort to word\n", },
+ COM "convert ushort to word\n", },
/* convert (u)int to (u)char */
{ SCONV, INAREG,
SAREG, TWORD,
SAREG, TCHAR|TUCHAR,
NAREG|NASL|NSPECIAL, RESC1,
- " andi. A1,AL,255 # convert (u)int to (u)char", },
-
-/* convert (u)int to (u)char */
-{ SCONV, INAREG,
- SAREG, TWORD,
- SANY, TCHAR|TUCHAR,
- 0, RLEFT,
- " # convert (u)int to (u)char\n", },
+ " andi. A1,AL,255" COM "convert (u)int to (u)char", },
/* convert (u)int to (u)short */
{ SCONV, INAREG,
SAREG, TWORD,
SAREG, TSHORT|TUSHORT,
NAREG|NASL|NSPECIAL, RESC1,
- " andi. A1,AL,65535 # convert (u)int to (u)short\n", },
+ " andi. A1,AL,65535" COM "convert (u)int to (u)short\n", },
+
+/* conversions on load from memory */
+
+/* char */
+{ SCONV, INAREG,
+ SOREG, TCHAR,
+ SAREG, TWORD,
+ NASL|NAREG|NSPECIAL, RESC1,
+ " lbz A1,AL" COM "convert char to int/long\n"
+ " extsb A1,A1\n", },
+
+/* uchar */
+{ SCONV, INAREG,
+ SOREG, TUCHAR,
+ SAREG, TWORD,
+ NASL|NAREG|NSPECIAL, RESC1,
+ " lbz A1,AL" COM "convert uchar to int/long\n", },
+
+/* short, ushort */
+{ SCONV, INAREG,
+ SOREG, TSHORT|TUSHORT,
+ SAREG, TWORD,
+ NASL|NAREG|NSPECIAL, RESC1,
+ " lha A1,AL" COM "convert (u)short to int/long\n", },
/*
* Subroutine calls.
@@ -217,37 +215,37 @@ struct optab table[] = {
SCON|SNAME, TANY,
SANY, TANY,
0, 0,
- " bl CL # call (args, no result) to scon/sname (CL)\n", },
+ " bl CL" COM "call (args, no result) to scon/sname (CL)\n", },
{ UCALL, FOREFF,
SCON|SNAME, TANY,
SANY, TANY,
0, 0,
- " bl CL # call (no args, no result) to scon/sname (CL)\n", },
+ " bl CL" COM "call (no args, no result) to scon/sname (CL)\n", },
{ CALL, INAREG,
SCON|SNAME, TANY,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT,
NAREG|NASL, RESC1, /* should be 0 */
- " bl CL # call (args, result in r3) to scon/sname (CL)\n", },
+ " bl CL" COM "call (args, result in r3) to scon/sname (CL)\n", },
{ CALL, INBREG,
SCON|SNAME, TANY,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1, /* should be 0 */
- " bl CL # call (args, result in r3:r4) to scon/sname (CL)\n", },
+ " bl CL" COM "call (args, result in r3:r4) to scon/sname (CL)\n", },
{ UCALL, INAREG,
SCON|SNAME, TANY,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT,
NAREG|NASL, RESC1, /* should be 0 */
- " bl CL # call (no args, result in r3) to scon/sname (CL)\n", },
+ " bl CL" COM "call (no args, result in r3) to scon/sname (CL)\n", },
{ UCALL, INBREG,
SCON|SNAME, TANY,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1, /* should be 0 */
- " bl CL # call (no args, result in r3:r4) to scon/sname (CL)\n", },
+ " bl CL" COM "call (no args, result in r3:r4) to scon/sname (CL)\n", },
/* struct return */
{ USTCALL, FOREFF,
@@ -293,22 +291,22 @@ struct optab table[] = {
/* XXX AL cannot be R0 */
{ PLUS, INAREG,
SAREG, TWORD|TPOINT,
- SONE, TANY,
- NSPECIAL, RLEFT,
- " addi AL,AL,AR # 1\n", },
+ SSCON, TANY,
+ NAREG|NASL|NSPECIAL, RESC1,
+ " addi A1,AL,AR" COM "addition of constant\n", },
/* XXX AL cannot be R0 */
-{ PLUS, INAREG,
+{ PLUS, INAREG|FORCC,
SAREG, TWORD|TPOINT,
SSCON, TANY,
- NAREG|NASL|NSPECIAL, RESC1,
- " addi A1,AL,AR # addition of constant\n", },
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " addic. A1,AL,AR" COM "addition of constant\n", },
{ PLUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SSCON, TANY,
NBREG|NBSL, RESC1,
- " addic A1,AL,AR # 64-bit addition of constant\n"
+ " addic A1,AL,AR" COM "64-bit addition of constant\n"
" addze U1,UL", },
{ PLUS, INAREG,
@@ -317,30 +315,36 @@ struct optab table[] = {
NAREG|NASL|NSPECIAL, RESC1,
" add A1,AL,AR\n", },
+{ PLUS, INAREG|FORCC,
+ SAREG, TWORD|TPOINT,
+ SAREG, TWORD|TPOINT,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " add. A1,AL,AR\n", },
+
{ PLUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1,
- " addc A1,AL,AR # 64-bit add\n"
+ " addc A1,AL,AR" COM "64-bit add\n"
" adde U1,UL,UR\n", },
{ MINUS, INAREG,
SAREG, TWORD|TPOINT,
- SONE, TANY,
+ SSCON, TANY,
NAREG|NASL|NSPECIAL, RESC1,
- " addi A1,AL,-1\n", },
+ " addi A1,AL,-AR\n", },
-{ MINUS, INAREG,
+{ MINUS, INAREG|FORCC,
SAREG, TWORD|TPOINT,
SSCON, TANY,
- NAREG|NASL|NSPECIAL, RESC1,
- " addi A1,AL,AR\n", },
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " addi. A1,AL,-AR\n", },
{ MINUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SSCON, TANY,
NBREG|NBSL, RESC1,
- " addic A1,AL,-AR"
+ " addic A1,AL,-AR\n"
" addme U1,UL\n", },
{ MINUS, INAREG,
@@ -349,11 +353,17 @@ struct optab table[] = {
NAREG|NASL|NSPECIAL, RESC1,
" subf A1,AR,AL\n", },
+{ MINUS, INAREG|FORCC,
+ SAREG, TWORD|TPOINT,
+ SAREG, TWORD|TPOINT,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " subf. A1,AR,AL\n", },
+
{ MINUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1,
- " subfc A1,AR,AL # 64-bit subtraction\n"
+ " subfc A1,AR,AL" COM "64-bit subtraction\n"
" subfe U1,UR,UL\n", },
/*
@@ -364,13 +374,25 @@ struct optab table[] = {
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
- " slw A1,AL,AR # left shift\n", },
+ " slw A1,AL,AR" COM "left shift\n", },
+
+{ LS, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL, RESC1,
+ " slw. A1,AL,AR" COM "left shift\n", },
{ LS, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SCON, TANY,
NAREG|NASL, RESC1,
- " slwi A1,AL,AR # left shift by constant\n", },
+ " slwi A1,AL,AR" COM "left shift by constant\n", },
+
+{ LS, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SCON, TANY,
+ NAREG|NASL, RESC1,
+ " slwi. A1,AL,AR" COM "left shift by constant\n", },
{ LS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
@@ -382,13 +404,25 @@ struct optab table[] = {
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
- " srw A1,AL,AR # right shift\n", },
+ " srw A1,AL,AR" COM "right shift\n", },
+
+{ RS, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL, RESC1,
+ " srw. A1,AL,AR" COM "right shift\n", },
{ RS, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SCON, TANY,
NAREG|NASL, RESC1,
- " srwi A1,AL,AR # right shift by constant\n", },
+ " srwi A1,AL,AR" COM "right shift by constant\n", },
+
+{ RS, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SCON, TANY,
+ NAREG|NASL, RESC1,
+ " srwi. A1,AL,AR" COM "right shift by constant\n", },
{ RS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
@@ -420,18 +454,18 @@ struct optab table[] = {
SAREG, TANY,
SCON, TANY,
0, RDEST,
- " lis AL,ha16(AR)\n"
- " addi AL,AL,lo16(AR)\n", },
+ " lis AL," HA16(AR) "\n"
+ " addi AL,AL," LO16(AR) "\n", },
/* assign constant to register */
{ ASSIGN, FOREFF|INBREG,
SBREG, TANY,
SCON, TANY,
0, RDEST,
- " lis AL,ha16(AR)\n"
- " addi AL,AL,lo16(AR)\n"
- " lis UL,ha16(UR)\n"\
- " addi UL,UL,lo16(UR)\n", },
+ " lis AL," HA16(AR) "\n"
+ " addi AL,AL," LO16(AR) "\n"
+ " lis UL," HA16(UR) "\n"\
+ " addi UL,UL," LO16(UR) "\n", },
/* assign memory to register */
{ ASSIGN, FOREFF|INAREG,
@@ -445,32 +479,32 @@ struct optab table[] = {
SAREG, TWORD|TPOINT,
SNAME, TWORD|TPOINT,
NSPECIAL, RDEST,
- " lis AL,ha16(AR) # assign sname to reg\n"
- " lwz AL,lo16(AR)(AL)\n", },
+ " lis AL," HA16(AR) COM "assign sname to reg\n"
+ " lwz AL," LO16(AR) "(AL)\n", },
/* assign memory to register */
{ ASSIGN, FOREFF|INBREG,
SBREG, TLONGLONG|TULONGLONG,
SOREG, TLONGLONG|TULONGLONG,
NSPECIAL, RDEST,
- " lwz AL,AR # assign llong to reg\n"
+ " lwz AL,AR" COM "assign llong to reg\n"
" lwz UL,UR\n" },
{ ASSIGN, FOREFF|INAREG,
SBREG, TLONGLONG|TULONGLONG,
SNAME, TLONGLONG|TULONGLONG,
NSPECIAL, RDEST,
- " lis AL,ha16(AR) # assign 64-bit sname to reg\n"
- " lwz AL,lo16(AR)(AL)\n"
- " lis UL,ha16(UR)\n"
- " lwz UL,lo16(UR)(UL)\n", },
+ " lis AL," HA16(AR) COM "assign 64-bit sname to reg\n"
+ " lwz AL," LO16(AR) "(AL)\n"
+ " lis UL," HA16(UR) "\n"
+ " lwz UL," LO16(UR) "(UL)\n", },
/* assign memory to register */
{ ASSIGN, FOREFF|INBREG,
SBREG, TLONGLONG|TULONGLONG,
SOREG, TSWORD,
NSPECIAL, RDEST,
- " lwz AL,AR # load int/pointer into llong\n"
+ " lwz AL,AR" COM "load int/pointer into llong\n"
" srawi UL,AR,31\n" },
/* assign memory to register */
@@ -478,7 +512,7 @@ struct optab table[] = {
SBREG, TLONGLONG|TULONGLONG,
SOREG, TUNSIGNED|TPOINT,
NSPECIAL, RDEST,
- " lwz AL,AR # load uint/pointer into (u)llong\n"
+ " lwz AL,AR" COM "load uint/pointer into (u)llong\n"
" li UL, 0\n" },
/* assign memory to register */
@@ -493,8 +527,8 @@ struct optab table[] = {
SAREG, TUCHAR,
SNAME, TUCHAR,
NSPECIAL, RDEST,
- " lis AL,ha16(AR) # assign uchar sname to reg\n"
- " lbz AL,lo16(AR)(AL)\n", },
+ " lis AL," HA16(AR) COM "assign uchar sname to reg\n"
+ " lbz AL," LO16(AR) "(AL)\n", },
/* assign memory to register */
{ ASSIGN, FOREFF|INAREG,
@@ -509,8 +543,8 @@ struct optab table[] = {
SAREG, TCHAR,
SNAME, TCHAR,
NSPECIAL, RDEST,
- " lis AL,ha16(AR) # assign char sname to reg\n"
- " lbz AL,lo16(AR)(AL)\n"
+ " lis AL," HA16(AR) COM "assign char sname to reg\n"
+ " lbz AL," LO16(AR) "(AL)\n"
" extsb AL,AL\n", },
/* assign memory to register */
@@ -525,8 +559,8 @@ struct optab table[] = {
SAREG, TWORD|TPOINT,
SNAME, TSHORT|TUSHORT,
NSPECIAL, RDEST,
- " lis AL,ha16(AR)\n"
- " lha AL,lo16(AR)(AL)\n", },
+ " lis AL," HA16(AR) "\n"
+ " lha AL," LO16(AR) "(AL)\n", },
/* assign register to memory */
{ ASSIGN, FOREFF|INAREG,
@@ -540,15 +574,15 @@ struct optab table[] = {
SNAME, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
NAREG|NSPECIAL, RDEST,
- " lis A1,ha16(AL) # assign reg to sname\n"
- " stw AR,lo16(AL)(A1)\n", },
+ " lis A1," HA16(AL) COM "assign reg to sname\n"
+ " stw AR," LO16(AL) "(A1)\n", },
/* assign register to memory */
{ ASSIGN, FOREFF|INBREG,
SOREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NSPECIAL, RDEST,
- " stw AR,AL # store 64-bit value\n"
+ " stw AR,AL" COM "store 64-bit value\n"
" stw UR,UL\n", },
/* assign register to memory */
@@ -556,10 +590,10 @@ struct optab table[] = {
SNAME, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NSPECIAL, RDEST,
- " lis A1,ha16(AL) # assign reg to 64-bit sname\n"
- " stw AR,lo16(AL)(A1)\n"
- " lis U1,ha16(UL)\n"
- " stw UR,lo16(UL)(U1)\n", },
+ " lis A1," HA16(AL) COM "assign reg to 64-bit sname\n"
+ " stw AR," LO16(AL) "(A1)\n"
+ " lis U1," HA16(UL) "\n"
+ " stw UR," LO16(UL) "(U1)\n", },
/* assign register to memory */
{ ASSIGN, FOREFF|INAREG,
@@ -573,8 +607,8 @@ struct optab table[] = {
SNAME, TCHAR|TUCHAR,
SAREG, TCHAR|TUCHAR,
NAREG|NSPECIAL, RDEST,
- " lis A1,ha16(AL)"
- " stb AR,lo16(AL)(A1)\n", },
+ " lis A1," HA16(AL)
+ " stb AR," LO16(AL) "(A1)\n", },
/* assign register to memory */
{ ASSIGN, FOREFF|INAREG,
@@ -588,24 +622,33 @@ struct optab table[] = {
SNAME, TSHORT|TUSHORT,
SAREG, TSHORT|TUSHORT,
NAREG|NSPECIAL, RDEST,
- " lis A1,ha16(AL)\n"
- " sth AR,lo16(AL)(A1)\n", },
+ " lis A1," HA16(AL) "\n"
+ " sth AR," LO16(AL) "(A1)\n", },
/* assign register to register */
{ ASSIGN, FOREFF|INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
0, RDEST,
- " mr AL,AR # assign AR to AL\n", },
+ " mr AL,AR" COM "assign AR to AL\n", },
{ ASSIGN, FOREFF|INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, RDEST,
- " mr AL,AR # assign UR:AR to UL:AL\n"
+ " mr AL,AR" COM "assign UR:AR to UL:AL\n"
" mr UL,UR\n", },
#if 0
+/* assign register to memory */
+{ ASSIGN, FOREFF,
+ SAREG, TPOINT,
+ SAREG, TWORD,
+ 0, RDEST,
+ " stw AR,0(AL)" COM "indirect assign\n", },
+#endif
+
+#if 0
{ ASSIGN, FOREFF|INAREG,
SFLD, TANY,
SAREG, TANY,
@@ -654,7 +697,7 @@ struct optab table[] = {
SAREG, TSWORD,
SAREG, TSWORD,
NAREG, RESC1,
- " divw A1,AL,AR # signed modulo\n"
+ " divw A1,AL,AR" COM "signed modulo\n"
" mullw A1,A1,AR\n"
" subf A1,A1,AL\n", },
@@ -662,7 +705,7 @@ struct optab table[] = {
SAREG, TWORD|TPOINT,
SAREG, TUWORD|TPOINT,
NAREG, RESC1,
- " divwu A1,AL,AR # unsigned modulo\n"
+ " divwu A1,AL,AR" COM "unsigned modulo\n"
" mullw A1,A1,AR\n"
" subf A1,A1,AL\n", },
@@ -697,42 +740,42 @@ struct optab table[] = {
*/
{ UMUL, INAREG,
- SANY, TPOINT|TWORD,
- SOREG, TPOINT|TWORD,
+ SANY, TANY,
+ SOREG, TWORD|TPOINT,
NAREG|NSPECIAL, RESC1,
- " lwz A1,AL # word load\n", },
+ " lwz A1,AL" COM "word load\n", },
{ UMUL, INAREG,
SANY, TANY,
SOREG, TCHAR,
NAREG|NSPECIAL, RESC1,
- " lbz A1,AL # char load\n"
+ " lbz A1,AL" COM "char load\n"
" extsb A1,A1\n", },
{ UMUL, INAREG,
SANY, TANY,
SOREG, TUCHAR,
NAREG|NSPECIAL, RESC1,
- " lbz A1,AL # uchar load\n", },
+ " lbz A1,AL" COM "uchar load\n", },
{ UMUL, INAREG,
SANY, TANY,
SOREG, TSHORT,
NAREG|NSPECIAL, RESC1,
- " lhz A1,AL # short load\n"
+ " lhz A1,AL" COM "short load\n"
" extsh A1,A1\n", },
{ UMUL, INAREG,
SANY, TANY,
SOREG, TUSHORT,
NAREG|NSPECIAL, RESC1,
- " lhz A1,AL # ushort load\n", },
+ " lhz A1,AL" COM "ushort load\n", },
{ UMUL, INBREG,
SANY, TANY,
SOREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " lwz A1,AL # 64-bit load\n"
+ " lwz A1,AL" COM "64-bit load\n"
" lwz U1,UL\n", },
/*
@@ -741,20 +784,34 @@ struct optab table[] = {
/* compare with constant */
{ OPLOG, FORCC,
- SAREG, TANY,
+ SAREG, TSWORD|TSHORT|TCHAR,
SSCON, TANY,
0, RESCC,
" cmpwi AL,AR\n", },
+/* compare with constant */
+{ OPLOG, FORCC,
+ SAREG, TUWORD|TPOINT|TUSHORT|TUCHAR,
+ SSCON, TANY,
+ 0, RESCC,
+ " cmplwi AL,AR\n", },
+
/* compare with register */
{ OPLOG, FORCC,
- SAREG, TWORD|TPOINT|TSHORT|TCHAR,
- SAREG, TWORD|TPOINT|TSHORT|TCHAR,
+ SAREG, TSWORD|TSHORT|TCHAR,
+ SAREG, TSWORD|TSHORT|TCHAR,
0, RESCC,
" cmpw AL,AR\n", },
/* compare with register */
{ OPLOG, FORCC,
+ SAREG, TUWORD|TPOINT|TUSHORT|TUCHAR,
+ SAREG, TUWORD|TPOINT|TUSHORT|TUCHAR,
+ 0, RESCC,
+ " cmplw AL,AR\n", },
+
+/* compare with register */
+{ OPLOG, FORCC,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, 0,
@@ -770,31 +827,35 @@ struct optab table[] = {
{ AND, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- NAREG|NASL|NSPECIAL, RESC1,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
" and A1,AL,AR\n", },
-#if 0
+{ AND, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL|NSPECIAL, RESC1,
+ " and. A1,AL,AR\n", },
+
/* AR must be positive */
-{ AND, INAREG,
- SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
- SSCON, TANY,
- 0, RLEFT,
- " andi. AL,AL,AR\n", },
-#endif
+{ AND, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
+ SPCON, TANY,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " andi. A1,AL,AR\n", },
{ AND, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1,
- " and A1,AL,AR # 64-bit and\n"
+ " and A1,AL,AR" COM "64-bit and\n"
" and U1,UL,UR\n" },
-{ AND, INBREG,
+{ AND, INBREG|FORCC,
SBREG, TLONGLONG|TULONGLONG,
- SSCON, TANY,
- 0, RLEFT,
- " andi. AL,AL,AR # 64-bit and with constant\n"
- " li UL,0\n" },
+ SPCON, TANY,
+ NBREG|NBSL, RESC1|RESCC,
+ " andi. A1,AL,AR" COM "64-bit and with constant\n"
+ " li U1,0\n" },
{ OR, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
@@ -802,24 +863,42 @@ struct optab table[] = {
NAREG|NASL|NSPECIAL, RESC1,
" or A1,AL,AR\n", },
+{ OR, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " or. A1,AL,AR\n", },
+
{ OR, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
SSCON, TANY,
- 0, RLEFT,
- " ori AL,AL,AR\n", },
+ NAREG|NASL|NSPECIAL, RESC1,
+ " ori A1,AL,AR\n", },
+
+{ OR, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
+ SSCON, TANY,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " ori. A1,AL,AR\n", },
{ OR, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
- 0, RLEFT,
- " or AL,AL,AR # 64-bit or\n"
- " or UL,UL,UR\n" },
+ NBREG|NBSL, RESC1,
+ " or A1,AL,AR" COM "64-bit or\n"
+ " or U1,UL,UR\n" },
{ OR, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SSCON, TANY,
- 0, RLEFT,
- " ori AL,AL,AR # 64-bit or with constant\n" },
+ NBREG|NBSL, RESC1,
+ " ori A1,AL,AR" COM "64-bit or with constant\n" },
+
+{ OR, INBREG|FORCC,
+ SBREG, TLONGLONG|TULONGLONG,
+ SSCON, TANY,
+ NBREG|NBSL, RESC1|RESCC,
+ " ori. A1,AL,AR" COM "64-bit or with constant\n" },
{ ER, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
@@ -827,24 +906,42 @@ struct optab table[] = {
NAREG|NASL|NSPECIAL, RESC1,
" xor A1,AL,AR\n", },
+{ ER, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " xor. A1,AL,AR\n", },
+
{ ER, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
SSCON, TANY,
- 0, RLEFT,
- " xori AL,AL,AR\n", },
+ NAREG|NASL|NSPECIAL, RESC1,
+ " xori A1,AL,AR\n", },
+
+{ ER, INAREG|FORCC,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TCHAR,
+ SSCON, TANY,
+ NAREG|NASL|NSPECIAL, RESC1|RESCC,
+ " xori. A1,AL,AR\n", },
{ ER, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSL, RESC1,
- " xor A1,AL,AR # 64-bit xor\n"
+ " xor A1,AL,AR" COM "64-bit xor\n"
" xor U1,UL,UR\n" },
{ ER, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SSCON, TANY,
- 0, RLEFT,
- " xori AL,AL,AR # 64-bit xor with constant\n" },
+ NBREG|NBSL, RESC1,
+ " xori A1,AL,AR" COM "64-bit xor with constant\n" },
+
+{ ER, INBREG|FORCC,
+ SBREG, TLONGLONG|TULONGLONG,
+ SSCON, TANY,
+ NBREG|NBSL, RESC1|RESCC,
+ " xori. A1,AL,AR" COM "64-bit xor with constant\n" },
/*
* Jumps.
@@ -855,13 +952,12 @@ struct optab table[] = {
0, RNOP,
" ba LL\n", },
-#ifdef GCC_COMPAT
{ GOTO, FOREFF,
SAREG, TANY,
SANY, TANY,
0, RNOP,
- " ba *AL\n", },
-#endif
+ " mtctr AL\n"
+ " bctr\n", },
/*
* Convert LTYPE to reg.
@@ -871,93 +967,83 @@ struct optab table[] = {
SANY, TANY,
SOREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " lwz A1,AL # load long from memory\n"
+ " lwz A1,AL" COM "load long from memory\n"
" lwz U1,UL\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
SNAME, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " lis A1,ha16(AL) # load long from sname\n"
- " lwz A1,lo16(AL)(A1)\n"
- " lis U1,ha16(UL)\n"
- " lwz U1,lo16(UL)(U1)\n", },
+ " lis A1," HA16(AL) COM "load long from sname\n"
+ " lwz A1," LO16(AL) "(A1)\n"
+ " lis U1," HA16(UL) "\n"
+ " lwz U1," LO16(UL) "(U1)\n", },
/* load word from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG, TWORD|TPOINT,
NAREG, RESC1,
- " lwz A1,AL # load word from memory\n", },
+ " lwz A1,AL" COM "load word from memory\n", },
/* load word from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
SNAME, TWORD|TPOINT,
NAREG|NSPECIAL, RESC1,
- " lis A1,ha16(AL) # load word from sname\n"
- " lwz A1,lo16(AL)(A1)\n", },
+ " lis A1," HA16(AL) COM "load word from sname\n"
+ " lwz A1," LO16(AL) "(A1)\n", },
/* load char from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG, TCHAR,
NAREG, RESC1,
- " lbz A1,AL # load char from memory\n"
- " extsb A1,A1\n", },
+ " lbz A1,AL" COM "load char from memory\n" },
/* load char from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
- SNAME, TCHAR,
+ SNAME, TCHAR|TUCHAR,
NAREG|NSPECIAL, RESC1,
- " lis A1,ha16(AL) # load char from sname\n"
- " lbz A1,lo16(AL)(A1)\n"
- " extsb A1,A1\n", },
+ " lis A1," HA16(AL) COM "load (u)char from sname\n"
+ " lbz A1," LO16(AL) "(A1)\n", },
/* load uchar from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
- SOREG, TUCHAR,
+ SOREG, TCHAR|TUCHAR,
NAREG, RESC1,
- " lbz A1,AL # load uchar from memory\n", },
-
-/* load uchar from memory */
-{ OPLTYPE, INAREG,
- SANY, TANY,
- SNAME, TUCHAR,
- NAREG|NSPECIAL, RESC1,
- " lis A1,ha16(AL) # load uchar from sname"
- " lbz A1,lo16(AL)(A1)\n", },
+ " lbz A1,AL" COM "load (u)char from memory\n", },
/* load short from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG, TSHORT|TUSHORT,
NAREG, RESC1,
- " lha A1,AL # load (u)short from memory\n", },
+ " lha A1,AL" COM "load (u)short from memory\n", },
/* load short from memory */
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG, TSHORT|TUSHORT,
NAREG|NSPECIAL, RESC1,
- " lis A1,ha16(AL) # load (u)short from sname\n"
- " lha A1,lo16(AL)(A1)\n", },
+ " lis A1," HA16(AL) COM "load (u)short from sname\n"
+ " lha A1," LO16(AL) "(A1)\n", },
/* load from 16-bit constant */
{ OPLTYPE, INAREG,
SANY, TANY,
SSCON, TANY,
NAREG, RESC1,
- " li A1,AL # load 16-bit constant\n", },
+ " li A1,AL" COM "load 16-bit constant\n", },
/* load from 16-bit constant */
{ OPLTYPE, INBREG,
SANY, TANY,
SSCON, TANY,
NBREG, RESC1,
- " li A1,AL # load 16-bit constant\n"
+ " li A1,AL" COM "load 16-bit constant\n"
" li U1,0\n", },
/* load from constant */
@@ -965,35 +1051,34 @@ struct optab table[] = {
SANY, TANY,
SCON, TANY,
NAREG|NASL|NSPECIAL, RESC1,
- " lis A1,ha16(AL) # load constant into register\n"
- " addi A1,A1,lo16(AL)\n", },
+ " lis A1," HA16(AL) COM "load constant into register\n"
+ " addi A1,A1," LO16(AL) "\n", },
/* load from constant */
{ OPLTYPE, INBREG,
SANY, TANY,
SCON, TANY,
NBREG, RESC1,
- " lis A1,ha16(AL) # load constant into register\n"
- " addi A1,A1,lo16(AL)\n"
- " lis U1,ha16(UL)\n"
- " addi U1,U1,lo16(UL)\n", },
+ " lis A1," HA16(AL) COM "load constant into register\n"
+ " addi A1,A1," LO16(AL) "\n"
+ " lis U1," HA16(UL) "\n"
+ " addi U1,U1," LO16(UL) "\n", },
/* load from register */
{ OPLTYPE, INAREG,
SANY, TANY,
SAREG, TANY,
NAREG, RESC1,
- " mr A1,AL # load AL into A1\n" },
+ " mr A1,AL" COM "load AL into A1\n" },
/* load from register */
{ OPLTYPE, INBREG,
SANY, TANY,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " mr A1,AL # load UL:AL into U1:A1\n"
+ " mr A1,AL" COM "load UL:AL into U1:A1\n"
" mr U1,UL\n", },
-
/*
* Negate a word.
*/