-ftp://pcc.ludd.ltu.se/pub/pcc/pcc-20160418.tgz
+ftp://pcc.ludd.ltu.se/pub/pcc/pcc-20160906.tgz
-/* $Id: code.c,v 1.85 2015/12/13 09:00:04 ragge Exp $ */
+/* $Id: code.c,v 1.86 2016/07/15 20:31:01 ragge Exp $ */
/*
* Copyright (c) 2008 Michael Shalayeff
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* will have the first 64 bits passed in general reg and the second in SSE.
*
* sp below is a pointer to a member list.
- * off tells whether is is the first or second eight-byte to check.
+ * off tells how many bits in that the classification should start.
*/
static int
-classifystruct(struct symtab *sp, int off)
+classifystruct(struct symtab *sp, int off, int osz)
{
struct symtab sps[16];
union dimfun *df;
TWORD t;
int cl, cl2, sz, i;
-
+//printf("classifystruct off %d, osz %d\n", off, osz);
for (cl = 0; sp; sp = sp->snext) {
t = sp->stype;
t = DECREF(t);
df++;
} while (ISARY(t));
+#ifdef PCC_DEBUG
+ if (sz >= 16)
+ cerror("classifystruct");
+#endif
for (i = 0; i < sz; i++) {
sps[i] = *sp;
sps[i].stype = t;
sps[i-1].snext = sp->snext;
sp = &sps[0];
}
-
- if (off == 0) {
- if (sp->soffset >= SZLONG)
- continue;
- } else {
- if (sp->soffset < SZLONG)
- continue;
- }
-
- if (t <= ULONGLONG || ISPTR(t)) {
- if (cl == 0 || cl == STRSSE)
- cl = STRREG;
- } else if (t <= DOUBLE) {
- if (cl == 0)
- cl = STRSSE;
- } else if (t == LDOUBLE) {
- return STRMEM;
- } else if (ISSOU(t)) {
+ if (sp->soffset >= osz)
+ break;
+ if (ISSOU(t)) {
#ifdef GCC_COMPAT
if (attr_find(sp->sap, GCC_ATYP_PACKED)) {
cl = STRMEM;
} else
#endif
- {
- cl2 = classifystruct(strmemb(sp->sap), off);
+ if ((sp->soffset +
+ tsize(sp->stype, sp->sdf, sp->sap)) < off) {
+ continue;
+ } else {
+ cl2 = classifystruct(strmemb(sp->sap),
+ off - sp->soffset, osz - sp->soffset);
if (cl2 == STRMEM) {
cl = STRMEM;
} else if (cl2 == STRREG) {
cl = STRSSE;
}
}
+ continue;
+ }
+
+ if (sp->soffset < off)
+ continue;
+
+ if (t <= ULONGLONG || ISPTR(t)) {
+ if (cl == 0 || cl == STRSSE)
+ cl = STRREG;
+ } else if (t <= DOUBLE) {
+ if (cl == 0)
+ cl = STRSSE;
+ } else if (t == LDOUBLE) {
+ return STRMEM;
} else
cerror("classifystruct: unknown type %x", t);
if (cl == STRMEM)
cl = STRMEM;
} else if (sz <= SZLONG) {
/* only one member to check */
- cl = classifystruct(strmemb(ap), 0);
+ cl = classifystruct(strmemb(ap), 0, SZLONG);
if (cl == STRREG && ngpr > 5)
cl = STRMEM;
else if (cl == STRSSE && nsse > 7)
cl = STRMEM;
} else {
- cl = classifystruct(strmemb(ap), 0);
- cl2 = classifystruct(strmemb(ap), 1);
+ cl = classifystruct(strmemb(ap), 0, SZLONG);
+ cl2 = classifystruct(strmemb(ap), SZLONG, 2*SZLONG);
if (cl == STRMEM || cl2 == STRMEM)
cl = STRMEM;
else if (cl == STRREG && cl2 == STRSSE)
-/* $Id: local2.c,v 1.62 2015/12/13 09:00:04 ragge Exp $ */
+/* $Id: local2.c,v 1.63 2016/08/08 16:35:49 ragge Exp $ */
/*
* Copyright (c) 2008 Michael Shalayeff
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
case SHORT: case USHORT: s = 'w'; break;
case INT: case UNSIGNED: s = 'l'; break;
default: s = 'q'; break;
- printf("%c", s);
}
+ printf("%c", s);
break;
case 'U': { /* output branch insn for ucomi */
-/* $Id: code.c,v 1.96 2015/11/17 19:19:40 ragge Exp $ */
+/* $Id: code.c,v 1.98 2016/08/09 17:16:58 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
return;
/* struct return for small structs */
- sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdf, cftnsp->sap);
+ sz = (int)tsize(BTYPE(cftnsp->stype), cftnsp->sdf, cftnsp->sap);
#if defined(os_openbsd)
if (sz == SZCHAR || sz == SZSHORT || sz == SZINT || sz == SZLONGLONG) {
#else
else if (sz > SZSHORT) sz = INT;
else sz = SHORT;
q = block(OREG, NIL, NIL, sz, 0, 0);
- p = block(REG, NIL, NIL, sz, 0, 0);
- ecomp(buildtree(ASSIGN, p, q));
+ if (sz < SZINT)
+ q = cast(q, INT, 0);
+ p = block(REG, NIL, NIL, INT, 0, 0);
+ p = (buildtree(ASSIGN, p, q));
+ ecomp(p);
return;
}
/* Function returns struct, create return arg node */
if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
- sz = tsize(BTYPE(cftnsp->stype), cftnsp->sdf, cftnsp->sap);
+ sz = (int)tsize(BTYPE(cftnsp->stype), cftnsp->sdf, cftnsp->sap);
#if defined(os_openbsd)
/* OpenBSD uses non-standard return for small structs */
if (sz > SZLONGLONG)
*/
for (i = 0; i < cnt; i++) {
sp2 = sp[i];
- sz = tsize(sp2->stype, sp2->sdf, sp2->sap);
+ sz = (int)tsize(sp2->stype, sp2->sdf, sp2->sap);
SETOFF(sz, SZINT);
if ((ISSOU(sp2->stype) && sp2->sclass == REGISTER) ||
(sp2->sclass == REGISTER && xtemps == 0)) {
/* must move to stack */
- sz = tsize(sp2->stype, sp2->sdf, sp2->sap);
+ sz = (int)tsize(sp2->stype, sp2->sdf, sp2->sap);
SETOFF(sz, SZINT);
SETOFF(autooff, SZINT);
reg = sp2->soffset;
NODE *q;
int sz, r;
- sz = tsize(p->n_type, p->n_df, p->n_ap)/SZCHAR;
+ sz = (int)tsize(p->n_type, p->n_df, p->n_ap)/SZCHAR;
sz = (sz + 3) >> 2; /* sz in regs */
if ((regcvt+sz) > rparg) {
regcvt = rparg;
-/* $Id: local.c,v 1.200 2016/03/05 15:31:24 ragge Exp $ */
+/* $Id: local.c,v 1.201 2016/08/09 17:30:26 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
r = p->n_right;
if (r->n_op != STCALL && r->n_op != USTCALL)
break;
- m = tsize(BTYPE(r->n_type), r->n_df, r->n_ap);
+ m = (int)tsize(BTYPE(r->n_type), r->n_df, r->n_ap);
if (m == SZCHAR)
m = CHAR;
else if (m == SZSHORT)
-/* $Id: macdefs.h,v 1.23 2016/03/05 15:53:04 ragge Exp $ */
+/* $Id: macdefs.h,v 1.24 2016/07/10 09:54:57 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
#define MAX_INT 0x7fffffff
#define MAX_UNSIGNED 0xffffffffU
#define MIN_LONG MIN_INT
-#define MAX_LONG MAX_INT
-#define MAX_ULONG MAX_UNSIGNED
+#define MAX_LONG 0x7fffffffL
+#define MAX_ULONG 0xffffffffUL
#define MIN_LONGLONG (-0x7fffffffffffffffLL-1)
#define MAX_LONGLONG 0x7fffffffffffffffLL
#define MAX_ULONGLONG 0xffffffffffffffffULL
Arrays allocated as automatics are stored on the stack with a pointer
in zero page to its destination.
+#ifdef 2bsd
0-7 Unused (by us)
10 Stack pointer
11 Frame pointer
40-47 Used by HW stack and MMPU
50-77 Permanent, save before use.
100-377 Addresses for subroutines, written by the linker
+#elif rdos
+0-17 Unused (by us)
+20-27 (Auto-increment), scratch
+30-37 (Auto-decrement), scratch
+40-47 Used by HW stack and MMPU
+50-377 Addresses for subroutines, written by the linker
+#endif
The normal registers (AC0-AC3) are all considered scratch registers.
In byte code the left half of a word is the first byte (big-endian).
This is bit 0-7 in Nova syntax.
-The stack is growing towards lower adresses (as opposed to the Eclipse stack).
+The stack is growing towards lower adresses (as opposed to the HW stack).
Stack pointer points to the last used stack entry, which means:
-PUSH: dec sp, store value
-POP: fetch val, inc sp
+PUSH: store value, dec sp
+POP: inc sp, fetch val
Note that internally is the first 24 words stored in loc 50-77!
So an offset is subtracted in adrput().
-Stack layout:
+Functions which modifies stack (like calls to alloca) will have a frame
+pointer to which everything relates. Functions that do not only have
+stack pointer.
+
+Space for all possible arguments are allocated on stack by the compiler,
+so no pushing and popping.
+
+Stack layout (with frame pointer):
- ! arg1 ! 1
- fp -> ! arg0 ! 0
- ! old pc! -1
- ! old fp! -2
- sp -> ! saved ! -3
+ ! arg1 ! 2
+ ! arg0 ! 1
+ fp -> ! ret pc! 0 <- stack pointer when enter new function
+ ! old fp! -1
+ sp -> ! saved ! -2
Stack references to zero page are converted to NAMEs, using word addresses.
-/* $Id: code.c,v 1.11 2014/06/03 20:19:50 ragge Exp $ */
+/* $Id: code.c,v 1.13 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
# include "pass1.h"
+#ifdef LANG_CXX
+#define P1ND NODE
+#define p1alloc talloc
+#define p1nfree nfree
+#define p1fwalk fwalk
+#define p1tcopy ccopy
+#endif
+
/*
* cause the alignment to become a multiple of n
* never called for text segment.
void
setseg(int seg, char *name)
{
+#ifndef os_none
switch (seg) {
case PROG: name = ".text"; break;
case DATA:
case LDATA: name = ".data"; break;
case STRNG:
- case RDATA: name = ".section .rodata"; break;
+ case RDATA: name = ".rodata"; break;
case UDATA: break;
default:
cerror((char *)__func__);
}
+#else
+ name = ".NREL";
+#endif
printf("\t%s\n", name);
}
{
char *name;
- if ((name = sp->soname) == NULL)
- name = exname(sp->sname);
+ name = getexname(sp);
if (ISFTN(sp->stype))
return;
int off, al;
char *name;
- if ((name = sp->soname) == NULL)
- name = exname(sp->sname);
+ name = getexname(sp);
off = tsize(sp->stype, sp->sdf, sp->sap);
SETOFF(off,SZCHAR);
off /= SZCHAR;
void
efcode(void)
{
- NODE *p, *q;
+ P1ND *p, *q;
// int sz;
#if 0
/* address of return struct is in eax */
/* create a call to memcpy() */
/* will get the result in eax */
- p = block(REG, NIL, NIL, CHAR+PTR, 0, 0);
+ p = block(REG, NULL, NULL, CHAR+PTR, 0, 0);
// p->n_rval = EAX;
- q = block(OREG, NIL, NIL, CHAR+PTR, 0, 0);
+ q = block(OREG, NULL, NULL, CHAR+PTR, 0, 0);
// q->n_rval = EBP;
- q->n_lval = 8; /* return buffer offset */
+ slval(q, 8); /* return buffer offset */
p = block(CM, q, p, INT, 0, 0);
// sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
// p = block(CM, p, bcon(sz), INT, 0, 0);
void
bfcode(struct symtab **a, int n)
{
-// NODE *p, *q;
+// P1ND *p, *q;
int i;
for (i = 0; i < n; i++) {
void
ejobcode(int flag)
{
+#ifdef os_none
+ printf("\t.END\n");
+#endif
}
void
bjobcode(void)
{
+#ifdef os_none
+ printf("\t.TITL foo\n");
+ printf("\t.TXTM 1\n"); /* big endian */
+ printf("\t.NREL\n"); /* relocatable */
+ printf("\t.EXTU\n"); /* undefined syms are external */
+#endif
}
/* fix up type of field p */
{
return 0;
}
+
+static int xoff;
+
+static void
+fnummer(P1ND *p)
+{
+ if (p->n_op != FUNARG)
+ return;
+ p->n_rval = xoff;
+ xoff += tsize(p->n_type, p->n_df, p->n_ap)/SZSHORT;
+}
+
/*
* Called with a function call with arguments as argument.
* This is done early in buildtree() and only done once.
*/
-NODE *
-funcode(NODE *p)
+P1ND *
+funcode(P1ND *p)
{
- NODE *r, *l;
+ P1ND *r, *l;
/* Fix function call arguments. On nova, just add funarg */
for (r = p->n_right; r->n_op == CM; r = r->n_left) {
- if (r->n_right->n_op != STARG)
- r->n_right = block(FUNARG, r->n_right, NIL,
+ if (r->n_right->n_op != STARG) {
+ r->n_right = block(FUNARG, r->n_right, NULL,
r->n_right->n_type, r->n_right->n_df,
r->n_right->n_ap);
+ }
}
if (r->n_op != STARG) {
- l = talloc();
+ l = p1alloc();
*l = *r;
r->n_op = FUNARG;
r->n_left = l;
r->n_type = l->n_type;
}
+ xoff = 1;
+ p1listf(p->n_right, fnummer);
return p;
}
/*
* Return return as given by a.
*/
-NODE *
-builtin_return_address(const struct bitable *bt, NODE *a)
+P1ND *
+builtin_return_address(const struct bitable *bt, P1ND *a)
{
cerror((char *)__func__);
return 0;
/*
* Return frame as given by a.
*/
-NODE *
-builtin_frame_address(const struct bitable *bt, NODE *a)
+P1ND *
+builtin_frame_address(const struct bitable *bt, P1ND *a)
{
cerror((char *)__func__);
return 0;
/*
* Return "canonical frame address".
*/
-NODE *
-builtin_cfa(const struct bitable *bt, NODE *a)
+P1ND *
+builtin_cfa(const struct bitable *bt, P1ND *a)
{
cerror((char *)__func__);
return 0;
-/* $Id: local.c,v 1.17 2015/08/18 10:15:08 ragge Exp $ */
+/* $Id: local.c,v 1.19 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
# include "pass1.h"
+# include "unicode.h"
+
+#ifdef LANG_CXX
+#define P1ND NODE
+#define p1alloc talloc
+#define p1nfree nfree
+#define p1fwalk fwalk
+#define p1tcopy ccopy
+#endif
/* this file contains code which is dependent on the target machine */
-NODE *
-clocal(NODE *p)
+P1ND *
+clocal(P1ND *p)
{
struct symtab *q;
- NODE *r, *l;
+ P1ND *r, *l;
TWORD t;
int o;
#ifdef PCC_DEBUG
if (xdebug) {
printf("clocal\n");
- fwalk(p, eprint, 0);
+ p1fwalk(p, eprint, 0);
}
#endif
switch (q->sclass) {
case PARAM:
case AUTO:
- if (0 && q->soffset < MAXZP * SZINT &&
- q->sclass != PARAM) {
- p->n_lval = -(q->soffset/SZCHAR) + ZPOFF*2;
- p->n_sp = NULL;
- } else {
- /* fake up a structure reference */
- r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
- r->n_lval = 0;
- r->n_rval = FPREG;
- p = stref(block(STREF, r, p, 0, 0, 0));
- }
+ /* fake up a structure reference */
+ r = block(REG, NULL, NULL, PTR+STRTY, 0, 0);
+ slval(r, 0);
+ r->n_rval = FPREG;
+ p = stref(block(STREF, r, p, 0, 0, 0));
break;
default:
break;
case PMCONV:
case PVCONV:
- if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
- nfree(p);
- p = (buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
+ if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
+ r = (buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
+ p1nfree(p);
+ p = r;
break;
case PCONV:
l->n_qual = p->n_qual;
l->n_df = p->n_df;
l->n_ap = p->n_ap;
- p = nfree(p);
- break;
- }
-
-#ifdef PCC_DEBUG
- if (xdebug) {
- printf("clocal end\n");
- fwalk(p, eprint, 0);
- }
-#endif
-
-#if 0
- register struct symtab *q;
- register NODE *r, *l;
- register int o;
- register int m;
- TWORD t;
-
-//printf("in:\n");
-//fwalk(p, eprint, 0);
- switch( o = p->n_op ){
-
- case NAME:
- if ((q = p->n_sp) == NULL)
- return p; /* Nothing to care about */
-
- switch (q->sclass) {
-
- case PARAM:
- case AUTO:
- /* fake up a structure reference */
- r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
- r->n_lval = 0;
- r->n_rval = FPREG;
- 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;
-
- }
- break;
-
- case STCALL:
- case CALL:
- /* Fix function call arguments. On x86, just add funarg */
- for (r = p->n_right; r->n_op == CM; r = r->n_left) {
- if (r->n_right->n_op != STARG &&
- r->n_right->n_op != FUNARG)
- r->n_right = block(FUNARG, r->n_right, NIL,
- r->n_right->n_type, r->n_right->n_df,
- r->n_right->n_sue);
- }
- if (r->n_op != STARG && r->n_op != FUNARG) {
- l = talloc();
- *l = *r;
- r->n_op = FUNARG; r->n_left = l; r->n_type = l->n_type;
- }
- break;
-
- case CBRANCH:
- l = p->n_left;
-
- /*
- * Remove unnecessary conversion ops.
- */
- if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
- if (coptype(l->n_op) != BITYPE)
- break;
- if (l->n_right->n_op == ICON) {
- r = l->n_left->n_left;
- if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
- break;
- /* Type must be correct */
- t = r->n_type;
- nfree(l->n_left);
- l->n_left = r;
- l->n_type = t;
- l->n_right->n_type = t;
- }
- }
- break;
-
- case PCONV:
- /* Remove redundant PCONV's. Be careful */
- l = p->n_left;
- if (l->n_op == ICON) {
- l->n_lval = (unsigned)l->n_lval;
- goto delp;
- }
- if (l->n_type < INT || l->n_type == LONGLONG ||
- l->n_type == ULONGLONG) {
- /* float etc? */
- p->n_left = block(SCONV, l, NIL,
- UNSIGNED, 0, 0);
- break;
- }
- /* if left is SCONV, cannot remove */
- if (l->n_op == SCONV)
- break;
- /* if conversion to another pointer type, just remove */
- if (p->n_type > BTMASK && l->n_type > BTMASK)
- goto delp;
- break;
-
- delp: 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;
+ p = p1nfree(p);
break;
- case SCONV:
- l = p->n_left;
-
- if (p->n_type == l->n_type) {
- nfree(p);
- return l;
- }
-
- if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
- btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
- if (p->n_type != FLOAT && p->n_type != DOUBLE &&
- l->n_type != FLOAT && l->n_type != DOUBLE &&
- l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
- if (l->n_op == NAME || l->n_op == UMUL ||
- l->n_op == TEMP) {
- l->n_type = p->n_type;
- nfree(p);
- return l;
- }
- }
- }
-
- if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
- coptype(l->n_op) == BITYPE) {
- l->n_type = p->n_type;
- nfree(p);
- return l;
- }
-
- o = l->n_op;
- m = p->n_type;
-
- if (o == ICON) {
- CONSZ val = l->n_lval;
-
- if (!ISPTR(m)) /* Pointers don't need to be conv'd */
- switch (m) {
- case CHAR:
- l->n_lval = (char)val;
- break;
- case UCHAR:
- l->n_lval = val & 0377;
- break;
- case SHORT:
- l->n_lval = (short)val;
- break;
- case USHORT:
- l->n_lval = val & 0177777;
- break;
- case ULONG:
- case UNSIGNED:
- l->n_lval = val & 0xffffffff;
- break;
- case LONG:
- case INT:
- l->n_lval = (int)val;
- break;
- case LONGLONG:
- l->n_lval = (long long)val;
- break;
- case ULONGLONG:
- l->n_lval = val;
- break;
- case VOID:
- break;
- case LDOUBLE:
- case DOUBLE:
- case FLOAT:
- l->n_op = FCON;
- l->n_dcon = val;
- break;
- default:
- cerror("unknown type %d", m);
- }
- l->n_type = m;
- l->n_sue = 0;
- nfree(p);
- return l;
- }
- if (DEUNSIGN(p->n_type) == SHORT &&
- DEUNSIGN(l->n_type) == SHORT) {
- nfree(p);
- p = l;
- }
- if ((p->n_type == CHAR || p->n_type == UCHAR ||
- p->n_type == SHORT || p->n_type == USHORT) &&
- (l->n_type == FLOAT || l->n_type == DOUBLE ||
- l->n_type == LDOUBLE)) {
- p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_sue);
- p->n_left->n_type = INT;
- return p;
- }
- break;
-
- case MOD:
- case DIV:
- if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
- break;
- if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
- break;
- /* make it an int division by inserting conversions */
- p->n_left = block(SCONV, p->n_left, NIL, INT, 0, 0);
- p->n_right = block(SCONV, p->n_right, NIL, INT, 0, 0);
- p = block(SCONV, p, NIL, p->n_type, 0, 0);
- p->n_left->n_type = INT;
- break;
-
- case PMCONV:
- case PVCONV:
- if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0);
- nfree(p);
- return(buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
-
case FORCE:
/* put return value in return reg */
p->n_op = ASSIGN;
p->n_right = p->n_left;
- p->n_left = block(REG, NIL, NIL, p->n_type, 0, 0);
+ p->n_left = block(REG, NULL, NULL, p->n_type, 0, 0);
p->n_left->n_rval = RETREG(p->n_type);
break;
- case LS:
- case RS:
- /* shift count must be in a char
- * unless longlong, where it must be int */
- if (p->n_right->n_op == ICON)
- break; /* do not do anything */
- if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
- if (p->n_right->n_type != INT)
- p->n_right = block(SCONV, p->n_right, NIL,
- INT, 0, 0);
- break;
- }
- if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
- break;
- p->n_right = block(SCONV, p->n_right, NIL,
- CHAR, 0, 0);
- break;
}
-//printf("ut:\n");
-//fwalk(p, eprint, 0);
+#ifdef PCC_DEBUG
+ if (xdebug) {
+ printf("clocal end\n");
+ p1fwalk(p, eprint, 0);
+ }
#endif
-
return(p);
}
void
-myp2tree(NODE *p)
+myp2tree(P1ND *p)
{
struct symtab *sp;
- NODE *l, *r;
+ P1ND *l, *r;
int o = p->n_op;
switch (o) {
case NAME: /* reading from a name must be done with a subroutine */
if (p->n_type != CHAR && p->n_type != UCHAR)
break;
- l = buildtree(ADDROF, ccopy(p), NIL);
- r = block(NAME, NIL, NIL, INT, 0, 0);
+ l = buildtree(ADDROF, p1tcopy(p), NULL);
+ r = block(NAME, NULL, NULL, INT, 0, 0);
r->n_sp = lookup(addname("__nova_rbyte"), SNORMAL);
if (r->n_sp->sclass == SNULL) {
r = clocal(r);
r = optim(buildtree(CALL, r, l));
*p = *r;
- nfree(r);
+ p1nfree(r);
break;
case FCON:
ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);
p->n_op = NAME;
- p->n_lval = 0;
+ slval(p, 0);
p->n_sp = sp;
}
}
/*ARGSUSED*/
int
-andable(NODE *p)
+andable(P1ND *p)
{
return(1); /* all names can have & taken on them */
}
* Be careful about only handling first-level pointers, the following
* indirections must be fullword.
*/
-NODE *
+P1ND *
offcon(OFFSZ off, TWORD t, union dimfun *d, struct attr *ap)
{
- register NODE *p;
+ register P1ND *p;
if (xdebug)
printf("offcon: OFFSZ %ld type %x dim %p siz %ld\n",
p = bcon(off/SZINT);
if (t == INCREF(CHAR) || t == INCREF(UCHAR) || t == INCREF(VOID))
- p->n_lval = off/SZCHAR; /* pointer to char */
+ slval(p, off/SZCHAR); /* pointer to char */
return(p);
}
* the allocated address.
*/
void
-spalloc(NODE *t, NODE *p, OFFSZ off)
+spalloc(P1ND *t, P1ND *p, OFFSZ off)
{
- NODE *sp;
+ P1ND *sp;
cerror("spalloc");
if ((off % SZINT) == 0)
cerror("roundsp");
/* save the address of sp */
- sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_ap);
- sp->n_lval = 0;
+ sp = block(REG, NULL, NULL, PTR+INT, t->n_df, t->n_ap);
+ slval(sp, 0);
sp->n_rval = STKREG;
t->n_type = sp->n_type;
ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
/* add the size to sp */
- sp = block(REG, NIL, NIL, p->n_type, 0, 0);
- sp->n_lval = 0;
+ sp = block(REG, NULL, NULL, p->n_type, 0, 0);
+ slval(sp, 0);
sp->n_rval = STKREG;
ecomp(buildtree(PLUSEQ, sp, p));
}
+#ifdef os_none
+/*
+ * Print out a string of characters.
+ * Assume that the assembler understands C-style escape
+ * sequences.
+ */
+void
+instring(struct symtab *sp)
+{
+ unsigned short sh[2];
+ char *s;
+ TWORD t;
+ P1ND *p;
+
+ locctr(STRNG, sp);
+ defloc(sp);
+
+ t = BTYPE(sp->stype);
+ s = sp->sname;
+ if (t == ctype(USHORT)) {
+ /* convert to UTF-16 */
+ p = xbcon(0, NULL, t);
+ while (*s) {
+ cp2u16(u82cp(&s), sh);
+ if ((glval(p) = sh[0]))
+ inval(0, SZSHORT, p);
+ if ((glval(p) = sh[1]))
+ inval(0, SZSHORT, p);
+ }
+ slval(p, 0);
+ inval(0, SZSHORT, p);
+ p1nfree(p);
+ } else if (t == ctype(SZINT < 32 ? ULONG : UNSIGNED) ||
+ t == ctype(SZINT < 32 ? LONG : INT)) {
+ /* convert to UTF-32 */
+ p = xbcon(0, NULL, t);
+ while (*s) {
+ slval(p, u82cp(&s));
+ inval(0, SZINT < 32 ? SZLONG : SZINT, p);
+ }
+ slval(p, 0);
+ inval(0, SZINT < 32 ? SZLONG : SZINT, p);
+ p1nfree(p);
+ } else if (t == CHAR || t == UCHAR) {
+ int chno = 0;
+ printf(PRTPREF "\t.TXT \"");
+ for (; *s; s++) {
+ if (*s == '\\') {
+ printf("<%o>", esccon(&s));
+ } else
+ printf("%c", *s);
+
+ if (chno++ >= 60) {
+ printf("\r\n" PRTPREF);
+ chno = 0;
+ }
+ }
+
+ printf("\"\n");
+ } else
+ cerror("instring %ld", t);
+}
+#endif
+
/*
* print out a constant node
* mat be associated with a label
*/
int
-ninval(CONSZ off, int fsz, NODE *p)
+ninval(CONSZ off, int fsz, P1ND *p)
{
switch (p->n_type) {
case FLOAT:
#endif
void
-calldec(NODE *p, NODE *q)
+calldec(P1ND *p, P1ND *q)
{
}
{
printf(LABFMT ":\n", label);
}
-
-static char *loctbl[] = { "text", "data", "section .rodata", "section .rodata" };
-
-void
-setloc1(int locc)
-{
- if (locc == lastloc)
- return;
- lastloc = locc;
- printf(" .%s\n", loctbl[locc]);
-}
#endif
/*
-/* $Id: local2.c,v 1.13 2015/03/28 08:28:46 ragge Exp $ */
+/* $Id: local2.c,v 1.16 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
# include "pass2.h"
# include <ctype.h>
# include <string.h>
+#include <stdlib.h>
void acon(NODE *p);
int argsize(NODE *p);
+static int totstk, maxargsz;
+struct conlbl { struct conlbl *next; int lbl; CONSZ l; char *n; int isch; };
+struct conlbl *pole;
+
+
void
deflab(int label)
{
void
prologue(struct interpass_prolog *ipp)
{
- int totstk;
-
- totstk = p2maxautooff/(SZINT/SZCHAR);
+ totstk = p2maxautooff/(SZINT/SZCHAR) + maxargsz;
+ maxargsz = 0;
+#ifdef os_none
+ if (ipp->ipp_vis)
+ printf(" .ENT %s\n", ipp->ipp_name);
+ printf(" .ZREL\n");
+ printf("%s: .%s\n", ipp->ipp_name, ipp->ipp_name);
+ printf(" .NREL\n");
+ printf(" 0%o\n", totstk);
+ printf(".%s:\n", ipp->ipp_name);
+#else
+ if (ipp->ipp_vis)
+ printf(" .globl %s\n", ipp->ipp_name);
if (totstk)
printf(" .word 0%o\n", totstk);
printf("%s:\n", ipp->ipp_name);
- if (ipp->ipp_vis)
- printf(" .globl %s\n", ipp->ipp_name);
- printf(" mov 3,0\n"); /* put ret pc in ac0 */
- printf(" jsr @16\n"); /* jump to prolog */
+#endif
+ printf(" sta 3,@csp\n"); /* put ret pc on stack */
+ printf(" jsr @prolog\n"); /* jump to prolog */
}
void
eoftn(struct interpass_prolog *ipp)
{
+ struct conlbl *w;
+ char *ch;
if (ipp->ipp_ip.ip_lbl == 0)
return; /* no code needs to be generated */
-
- printf(" jmp @17\n");
+ printf(" jmp @epilog\n");
+ if (pole == NULL)
+ return;
+ while (pole != NULL) {
+ w = pole, pole = w->next;
+ printf("." LABFMT ":\t", w->lbl);
+ ch = w->isch ? "*2" : "";
+ if (w->n[0])
+ printf("%s%s%s", w->n, ch, w->l ? "+" : "");
+ if (w->l || w->n[0] == 0)
+ printf(CONFMT "%s", w->l, ch);
+ printf("\n");
+ free(w);
+ }
}
/*
}
#endif
+static void
+addacon(int lbl, CONSZ lval, char *name, int isch)
+{
+ struct conlbl *w = xmalloc(sizeof(struct conlbl));
+ w->next = pole, pole = w;
+ w->lbl = lbl;
+ w->l = lval;
+ w->n = name;
+ w->isch = isch;
+}
+
void
zzzcode(NODE *p, int c)
{
+ struct conlbl *w;
+ char *ch;
int pr;
switch (c) {
- case 'C': /* remove from stack after subroutine call */
- pr = p->n_qual;
- switch (pr) {
- case 1:
- printf("\tisz sp\n");
- break;
- case 2:
- printf("\tisz sp\n\tisz sp\n");
+ case 'A':
+ if (pole == NULL)
break;
- case 3:
- printf("\tisz sp\n\tisz sp\n\tisz sp\n");
- break;
- case 4:
- printf("\tisz sp\n\tisz sp\n\tisz sp\n\tisz sp\n");
- break;
- default:
- printf(" lda 2,[0%o]\n", pr);
- printf(" lda 3,sp\n");
- printf(" add 2,3\n");
- printf(" sta 3,sp\n");
- break;
- }
- break;
-#if 0
- case 'A': /* print out a skip ending if any numbers in queue */
- if (ldq == NULL)
- return;
- printf(",skp\n.LP%d: .word 0%o", ldq->lab, ldq->val);
- if (ldq->name && *ldq->name)
- printf("+%s", ldq->name);
- printf("\n");
- ldq = ldq->next;
- break;
-
- case 'B': /* print a label for later load */
- ld = tmpalloc(sizeof(struct ldq));
- ld->val = p->n_lval;
- ld->name = p->n_name;
- ld->lab = prolnum++;
- ld->next = ldq;
- ldq = ld;
- printf(".LP%d-.", ld->lab);
- break;
-
- case 'C': /* fix reference to external variable via indirection */
- zzzcode(p->n_left, 'B');
+ w = pole, pole = w->next;
+ printf(",skp\n." LABFMT ":\t", w->lbl);
+ ch = w->isch ? "*2" : "";
+ if (w->n[0])
+ printf("%s%s%s", w->n, ch, w->l ? "+" : "");
+ if (w->l || w->n[0] == 0)
+ printf(CONFMT "%s", w->l, ch);
+ free(w);
break;
- case 'D': /* fix reference to external variable via indirection */
- zzzcode(p, 'B');
+ case 'B': /* push arg relative sp */
+ printf("%d,", p->n_rval);
+ expand(p, 0, "A1");
break;
-#endif
default:
comperr("zzzcode %c", c);
void
conput(FILE *fp, NODE *p)
{
- int val = p->n_lval;
+ int val = getlval(p);
switch (p->n_op) {
case ICON:
case NAME:
case OREG:
- p->n_lval += size;
+ setlval(p, getlval(p) + size);
adrput(stdout, p);
- p->n_lval -= size;
+ setlval(p, getlval(p) - size);
break;
case ICON:
- printf("$" CONFMT, p->n_lval >> 32);
+ printf("$" CONFMT, getlval(p) >> 32);
break;
default:
comperr("upput bad op %d size %d", p->n_op, size);
switch (p->n_op) {
case ICON:
+#if 1
/* addressable value of the constant */
+ printf("." LABFMT, i = getlab2());
+ addacon(i, getlval(p), p->n_name,
+ p->n_type == INCREF(CHAR) || p->n_type == INCREF(UCHAR));
+#else
fputc('[', io);
if (p->n_type == INCREF(CHAR) || p->n_type == INCREF(UCHAR))
printf(".byteptr ");
conput(io, p);
fputc(']', io);
+#endif
break;
case NAME:
if (p->n_name[0] != '\0') {
fputs(p->n_name, io);
- if (p->n_lval != 0)
- fprintf(io, "+" CONFMT, p->n_lval);
+ if (getlval(p) != 0)
+ fprintf(io, "+" CONFMT, getlval(p));
} else
- fprintf(io, CONFMT, p->n_lval);
- break;;
+ fprintf(io, CONFMT, getlval(p));
+ break;
case OREG:
if (p->n_name[0])
comperr("name in OREG");
- i = (int)p->n_lval;
+ i = (int)getlval(p);
if (i < 0) {
putchar('-');
i = -i;
void
mycanon(NODE *p)
{
+ int size = 0;
+
+ p->n_qual = 0;
+ if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
+ return;
+ for (p = p->n_right; p->n_op == CM; p = p->n_left) {
+ if (p->n_right->n_op != ASSIGN)
+ size += szty(p->n_right->n_type);
+ }
+ if (p->n_op != ASSIGN)
+ size += szty(p->n_type);
+
+ if (maxargsz < size)
+ maxargsz = size;
+
}
void
void
rmove(int s, int d, TWORD t)
{
- comperr("rmove");
+ printf(" mov %s,%s\n", rnames[s], rnames[d]);
+ if (t > UNSIGNED && !ISPTR(t))
+ comperr("rmove");
}
/*
}
char *rnames[] = {
- "0", "1", "2", "3", "2", "3", "fp", "sp"
+ "0", "1", "2", "3", "2", "3", "cfp", "csp"
};
/*
size += szty(p->n_type);
op->n_qual = size; /* XXX */
+ if (maxargsz < size)
+ maxargsz = size;
}
/*
return 0;
}
+#ifdef MYSTOREMOD
void
storemod(NODE *q, int off, int reg)
{
if (off < MAXZP*2) {
q->n_op = NAME;
q->n_name = "";
- q->n_lval = -off/2 + ZPOFF;
+ setlval(q, -off/2 + ZPOFF);
} else {
l = mklnode(REG, 0, reg, INCREF(q->n_type));
r = mklnode(ICON, off, 0, INT);
}
q->n_rval = q->n_su = 0;
}
+#endif
-/* $Id: macdefs.h,v 1.10 2016/03/05 15:53:04 ragge Exp $ */
+/* $Id: macdefs.h,v 1.12 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
#define BACKAUTO /* stack grows negatively for automatics */
#define BACKTEMP /* stack grows negatively for temporaries */
-#define ARGINIT 0 /* first arg at 0 offset */
+#define ARGINIT 16 /* first arg at 0 offset */
#define AUTOINIT 32 /* first var below 32-bit offset */
* B - AC2-AC3 (as index registers) : reg 4-5
* FP/SP as 6/7.
*/
+#define AC0 0
+#define AC1 1
+#define AC2 2
+#define AC3 3
+
#define MAXREGS 8 /* 0-29 */
#define RSTATUS \
#define MAXZP 030 /* number of locations used as stack */
#define ZPOFF 050 /* offset of zero page regs */
-#define MYSTOREMOD
+#ifdef os_none
+#define MYINSTRING
+#endif
+#undef MYSTOREMOD
#define MYLONGTEMP(p,w) { \
if (w->r_class == 0) { \
w->r_color = freetemp(szty(p->n_type)); \
} \
if (w->r_color < MAXZP*2) { /* color in bytes */ \
p->n_op = NAME; \
- p->n_lval = w->r_color/2 + ZPOFF; \
+ setlval(p, w->r_color/2 + ZPOFF); \
p->n_name = ""; \
break; \
} \
-/* $Id: order.c,v 1.6 2014/06/03 20:19:50 ragge Exp $ */
+/* $Id: order.c,v 1.7 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
struct rspecial *
nspecial(struct optab *q)
{
+ switch (q->op) {
+ case UMUL:
+ {
+ static struct rspecial s[] = {
+ { NLEFT, 4 }, { NRES, AC0 },
+ { NEVER, AC3 }, { NEVER, AC0 }, };
+ return s;
+ }
+
+ }
comperr("nspecial entry %d", q - table);
return 0; /* XXX gcc */
}
-/* $Id: table.c,v 1.3 2014/06/03 20:19:50 ragge Exp $ */
+/* $Id: table.c,v 1.4 2016/06/27 11:47:06 ragge Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
/* First entry must be an empty entry */
{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
+/*
+ * Conversions.
+ */
+/* uchar to (u)int */
+{ SCONV, INAREG,
+ SAREG, TUCHAR,
+ SAREG, TINT|TUNSIGNED,
+ 0, RLEFT,
+ "", },
+
/*
* All ASSIGN entries.
*/
SANY, TANY,
SONE, TWORD,
NAREG|NBREG, RESC1,
- " subzl A1,A1 # 1\n", },
+ " subzl A1,A1\n", },
/* constant -> reg */
{ OPLTYPE, INAREG|INBREG,
/* reg -> B-reg */
{ OPLTYPE, INBREG,
SANY, TANY,
- SAREG|SBREG, TWORD,
+ SAREG|SBREG, TWORD|TPOINT,
NBREG, RESC1,
" mov AR,A1\n", },
/*
* Indirections
*/
+#ifdef nova4
{ UMUL, INAREG,
- SANY, TPOINT|TWORD,
- SOREG, TPOINT|TWORD,
+ SANY, TPTRTO|TCHAR|TUCHAR,
+ SOREG|SAREG|SBREG|SNAME, TCHAR|TUCHAR,
NAREG|NASL, RESC1,
- " lda A1,AL #\n", },
+ " ldb A1,AL\n", },
+#endif
+{ UMUL, INAREG,
+ SANY, TPTRTO|TUCHAR,
+ SOREG, TUCHAR,
+ NSPECIAL|NAREG, RESC1,
+ " jsr @lbyt\n", },
+
+{ UMUL, INAREG,
+ SANY, TPTRTO|TCHAR,
+ SOREG, TCHAR,
+ NSPECIAL|NAREG, RESC1,
+ " jsr @lsbyt\n", },
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
- SOREG, TCHAR|TUCHAR,
+ SOREG, TPOINT|TWORD,
NAREG|NASL, RESC1,
- " lda A1,AL #\n", },
+ " lda A1,AL\n", },
{ UMUL, INBREG,
SANY, TPOINT|TWORD,
SOREG, TPOINT|TWORD,
NBREG|NBSL, RESC1,
- " lda A1,AL # #\n", },
-
-#if 0
-
-/* PCONVs are usually not necessary */
-{ PCONV, INAREG,
- SAREG, TWORD|TPOINT,
- SAREG, TWORD|TPOINT,
- 0, RLEFT,
- "", },
+ " lda A1,AL\n", },
/*
- * A bunch conversions of integral<->integral types
- * There are lots of them, first in table conversions to itself
- * and then conversions from each type to the others.
+ * logops
*/
+{ EQ, FOREFF,
+ SAREG|SBREG, TANY,
+ SZERO, TANY,
+ 0, RNOP,
+ " mov# AL,AL,snr\n jmp LC\n", },
-/* itself to itself, including pointers */
-
-/* convert (u)char to (u)char. */
-{ SCONV, INCH,
- SHCH, TCHAR|TUCHAR,
- SHCH, TCHAR|TUCHAR,
- 0, RLEFT,
- "", },
-
-/* convert pointers to int. */
-{ SCONV, ININT,
- SHINT, TPOINT|TWORD,
- SANY, TWORD,
- 0, RLEFT,
- "", },
-
-/* convert (u)longlong to (u)longlong. */
-{ SCONV, INLL,
- SHLL, TLL,
- SHLL, TLL,
- 0, RLEFT,
- "", },
-
-/* convert double <-> float. nothing to do here */
-{ SCONV, INFL,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- "", },
-
-/* convert pointers to pointers. */
-{ SCONV, ININT,
- SHINT, TPOINT,
- SANY, TPOINT,
- 0, RLEFT,
- "", },
-
-/* char to something */
-
-/* convert char to (unsigned) short. */
-{ SCONV, ININT,
- SBREG|SOREG|SNAME, TCHAR,
- SAREG, TSHORT|TUSHORT,
- NASL|NAREG, RESC1,
- " movsbw AL,A1\n", },
-
-/* convert unsigned char to (u)short. */
-{ SCONV, ININT,
- SHCH|SOREG|SNAME, TUCHAR,
- SAREG, TSHORT|TUSHORT,
- NASL|NAREG, RESC1,
- " movzbw AL,A1\n", },
-
-/* convert signed char to int (or pointer). */
-{ SCONV, ININT,
- SHCH|SOREG|SNAME, TCHAR,
- SAREG, TWORD|TPOINT,
- NASL|NAREG, RESC1,
- " movsbl AL,A1\n", },
-
-/* convert unsigned char to (u)int. */
-{ SCONV, ININT,
- SHCH|SOREG|SNAME, TUCHAR,
- SAREG, TWORD,
- NASL|NAREG, RESC1,
- " movzbl AL,A1\n", },
-
-/* convert char to (u)long long */
-{ SCONV, INLL,
- SHCH|SOREG|SNAME, TCHAR,
- SANY, TLL,
- NSPECIAL|NAREG|NASL, RESC1,
- " movsbl AL,%eax\n cltd\n", },
-
-/* convert unsigned char to (u)long long */
-{ SCONV, INLL,
- SHCH|SOREG|SNAME, TUCHAR,
- SANY, TLL,
- NCREG|NCSL, RESC1,
- " movzbl AL,A1\n xorl U1,U1\n", },
-
-/* convert char (in register) to double XXX - use NTEMP */
-{ SCONV, INFL,
- SHCH|SOREG|SNAME, TCHAR,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NAREG|NASL|NDREG, RESC2,
- " movsbl AL,A1\n pushl A1\n"
- " fildl (%esp)\n addl $4,%esp\n", },
-
-/* convert (u)char (in register) to double XXX - use NTEMP */
-{ SCONV, INFL,
- SHCH|SOREG|SNAME, TUCHAR,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NAREG|NASL|NDREG, RESC2,
- " movzbl AL,A1\n pushl A1\n"
- " fildl (%esp)\n addl $4,%esp\n", },
-
-/* short to something */
-
-/* convert short (in memory) to char */
-{ SCONV, INCH,
- SNAME|SOREG, TSHORT|TUSHORT,
- SHCH, TCHAR|TUCHAR,
- NBREG|NBSL, RESC1,
- " movb AL,A1\n", },
-
-/* convert short (in reg) to char. */
-{ SCONV, INCH,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL|NBREG|NBSL, RESC1,
- "ZM", },
-
-/* convert short to (u)int. */
-{ SCONV, ININT,
- SAREG|SOREG|SNAME, TSHORT,
- SAREG, TWORD,
- NASL|NAREG, RESC1,
- " movswl AL,A1\n", },
-
-/* convert unsigned short to (u)int. */
-{ SCONV, ININT,
- SAREG|SOREG|SNAME, TUSHORT,
- SAREG, TWORD,
- NASL|NAREG, RESC1,
- " movzwl AL,A1\n", },
-
-/* convert short to (u)long long */
-{ SCONV, INLL,
- SAREG|SOREG|SNAME, TSHORT,
- SHLL, TLL,
- NSPECIAL|NCREG|NCSL, RESC1,
- " movswl AL,%eax\n cltd\n", },
-
-/* convert unsigned short to (u)long long */
-{ SCONV, INLL,
- SAREG|SOREG|SNAME, TUSHORT,
- SHLL, TLL,
- NCREG|NCSL, RESC1,
- " movzwl AL,A1\n xorl U1,U1\n", },
-
-/* convert short (in memory) to float/double */
-{ SCONV, INFL,
- SOREG|SNAME, TSHORT,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- NDREG, RESC1,
- " fild AL\n", },
-
-/* convert short (in register) to float/double */
-{ SCONV, INFL,
- SAREG, TSHORT,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- NTEMP|NDREG, RESC1,
- " pushw AL\n fild (%esp)\n addl $2,%esp\n", },
-
-/* convert unsigned short to double XXX - use NTEMP */
-{ SCONV, INFL,
- SAREG|SOREG|SNAME, TUSHORT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NAREG|NASL|NDREG|NTEMP, RESC2,
- " movzwl AL,A1\n pushl A1\n"
- " fildl (%esp)\n addl $4,%esp\n", },
-
-/* int to something */
-
-/* convert int to char. This is done when register is loaded */
-{ SCONV, INCH,
- SAREG, TWORD,
- SANY, TCHAR|TUCHAR,
- NSPECIAL|NBREG|NBSL, RESC1,
- "ZM", },
-
-/* convert int to short. Nothing to do */
-{ SCONV, INAREG,
- SAREG, TWORD,
- SANY, TSHORT|TUSHORT,
- 0, RLEFT,
- "", },
-
-/* convert int to long long */
-{ SCONV, INLL,
- SAREG, TWORD|TPOINT,
- SCREG, TLONGLONG,
- NSPECIAL|NCREG|NCSL, RESC1,
- " cltd\n", },
-
-/* convert int to unsigned long long */
-{ SCONV, INLL,
- SAREG|SOREG|SNAME, TWORD|TPOINT,
- SHLL, TULONGLONG,
- NCSL|NCREG, RESC1,
- " movl AL,A1\n xorl U1,U1\n", },
-
-/* convert int (in memory) to double */
-{ SCONV, INFL,
- SOREG|SNAME, TWORD,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NDREG, RESC1,
- " fildl AL\n", },
-
-/* convert int (in register) to double */
-{ SCONV, INFL,
- SAREG, TWORD,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NTEMP|NDREG, RESC1,
- " pushl AL\n fildl (%esp)\n addl $4,%esp\n", },
-
-/* long long to something */
-
-/* convert (u)long long to (u)char (mem->reg) */
-{ SCONV, INCH,
- SOREG|SNAME, TLL,
- SANY, TCHAR|TUCHAR,
- NAREG|NASL, RESC1,
- " movb AL,A1\n", },
-
-/* convert (u)long long to (u)char (reg->reg, hopefully nothing) */
-{ SCONV, INCH,
- SHLL, TLL,
- SANY, TCHAR|TUCHAR,
- NAREG|NASL, RESC1,
- "ZS", },
-
-/* convert (u)long long to (u)short (mem->reg) */
-{ SCONV, INAREG,
- SOREG|SNAME, TLL,
- SAREG, TSHORT|TUSHORT,
- NAREG|NASL, RESC1,
- " movw AL,A1\n", },
-
-/* convert (u)long long to (u)short (reg->reg, hopefully nothing) */
-{ SCONV, INAREG,
- SHLL|SOREG|SNAME, TLL,
- SAREG, TSHORT|TUSHORT,
- NAREG|NASL, RESC1,
- "ZS", },
-
-/* convert long long to int (mem->reg) */
-{ SCONV, INAREG,
- SOREG|SNAME, TLL,
- SAREG, TWORD|TPOINT,
- NAREG|NASL, RESC1,
- " movl AL,A1\n", },
-
-/* convert long long to int (reg->reg, hopefully nothing) */
-{ SCONV, INAREG,
- SHLL|SOREG|SNAME, TLL,
- SAREG, TWORD|TPOINT,
- NAREG|NASL, RESC1,
- "ZS", },
-
-/* convert long long (in memory) to floating */
-{ SCONV, INFL,
- SOREG|SNAME, TLONGLONG,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NDREG, RESC1,
- " fildq AL\n", },
-
-/* convert long long (in register) to floating */
-{ SCONV, INFL,
- SHLL, TLONGLONG,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- NTEMP|NDREG, RESC1,
- " pushl UL\n pushl AL\n"
- " fildq (%esp)\n addl $8,%esp\n", },
-
-/* convert unsigned long long to floating */
-{ SCONV, INFL,
- SCREG, TULONGLONG,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- NDREG, RESC1,
- "ZJ", },
-
-/* float to something */
-
-#if 0 /* go via int by adding an extra sconv in clocal() */
-/* convert float/double to (u) char. XXX should use NTEMP here */
-{ SCONV, INCH,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- NBREG, RESC1,
- " subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
-
-/* convert float/double to (u) int/short/char. XXX should use NTEMP here */
-{ SCONV, INCH,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- NCREG, RESC1,
- " subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
-#endif
-
-/* convert float/double to (u)int. XXX should use NTEMP here */
-{ SCONV, INAREG,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SAREG, TWORD,
- NAREG, RESC1,
- " subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
+{ EQ, FOREFF,
+ SAREG|SBREG, TANY,
+ SAREG|SBREG, TANY,
+ 0, RNOP,
+ " sub# AL,AR,snr\n jmp LC\n", },
-/* convert float/double (in register) to (unsigned) long long */
-/* XXX - unsigned is not handled correct */
-{ SCONV, INLL,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHLL, TLONGLONG|TULONGLONG,
- NCREG, RESC1,
- " subl $8,%esp\n fistpq (%esp)\n"
- " popl A1\n popl U1\n", },
+{ NE, FOREFF,
+ SAREG|SBREG, TANY,
+ SZERO, TANY,
+ 0, RNOP,
+ " mov# AL,AL,szr\n jmp LC\n", },
-/* slut sconv */
-#endif
+{ NE, FOREFF,
+ SAREG|SBREG, TANY,
+ SAREG|SBREG, TANY,
+ 0, RNOP,
+ " sub# AL,AR,szr\n jmp LC\n", },
/*
* Subroutine calls.
SCON, TANY,
SANY, TANY,
0, 0,
- " jsr CL\nZC", },
+ " jsr @CL\n", },
{ UCALL, FOREFF,
SCON, TANY,
SANY, TANY,
0, 0,
- " jsr CL\n", },
+ " jsr @CL\n", },
{ CALL, INAREG|FOREFF,
SCON, TANY,
SANY, TANY,
NAREG|NASL, RESC1,
- " jsr CL\nZC", },
+ " jsr @CL\n", },
{ UCALL, INAREG|FOREFF,
SCON, TANY,
SANY, TANY,
NAREG|NASL, RESC1,
- " jsr CL\n", },
-
-#if 0
-{ CALL, INAREG,
- SCON, TANY,
- SAREG, TWORD|TPOINT,
- NAREG|NASL, RESC1, /* should be 0 */
- " call CL\nZC", },
-
-{ UCALL, INAREG,
- SCON, TANY,
- SAREG, TWORD|TPOINT,
- NAREG|NASL, RESC1, /* should be 0 */
- " call CL\n", },
-
-{ CALL, INBREG,
- SCON, TANY,
- SBREG, TCHAR|TUCHAR,
- NBREG, RESC1, /* should be 0 */
- " call CL\nZC", },
-
-{ UCALL, INBREG,
- SCON, TANY,
- SBREG, TCHAR|TUCHAR,
- NBREG, RESC1, /* should be 0 */
- " call CL\n", },
-
-{ CALL, INCREG,
- SCON, TANY,
- SCREG, TANY,
- NCREG|NCSL, RESC1, /* should be 0 */
- " call CL\nZC", },
-
-{ UCALL, INCREG,
- SCON, TANY,
- SCREG, TANY,
- NCREG|NCSL, RESC1, /* should be 0 */
- " call CL\n", },
-
-{ CALL, INDREG,
- SCON, TANY,
- SDREG, TANY,
- NDREG|NDSL, RESC1, /* should be 0 */
- " call CL\nZC", },
-
-{ UCALL, INDREG,
- SCON, TANY,
- SDREG, TANY,
- NDREG|NDSL, RESC1, /* should be 0 */
- " call CL\nZC", },
-
-{ CALL, FOREFF,
- SAREG, TANY,
- SANY, TANY,
- 0, 0,
- " call *AL\nZC", },
-
-{ UCALL, FOREFF,
- SAREG, TANY,
- SANY, TANY,
- 0, 0,
- " call *AL\nZC", },
-
-{ CALL, INAREG,
- SAREG, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ UCALL, INAREG,
- SAREG, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ CALL, INBREG,
- SAREG, TANY,
- SANY, TANY,
- NBREG|NBSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ UCALL, INBREG,
- SAREG, TANY,
- SANY, TANY,
- NBREG|NBSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ CALL, INCREG,
- SAREG, TANY,
- SANY, TANY,
- NCREG|NCSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ UCALL, INCREG,
- SAREG, TANY,
- SANY, TANY,
- NCREG|NCSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ CALL, INDREG,
- SAREG, TANY,
- SANY, TANY,
- NDREG|NDSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-{ UCALL, INDREG,
- SAREG, TANY,
- SANY, TANY,
- NDREG|NDSL, RESC1, /* should be 0 */
- " call *AL\nZC", },
-
-/* struct return */
-{ USTCALL, FOREFF,
- SCON, TANY,
- SANY, TANY,
- NAREG|NASL, 0,
- "ZP call CL\nZC", },
-
-{ USTCALL, INAREG,
- SCON, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- "ZP call CL\nZC", },
+ " jsr @CL\n", },
-{ USTCALL, INAREG,
- SNAME|SAREG, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- "ZP call *AL\nZC", },
-
-{ STCALL, FOREFF,
+{ GOTO, FOREFF,
SCON, TANY,
- SANY, TANY,
- NAREG|NASL, 0,
- "ZP call CL\nZC", },
-
-{ STCALL, INAREG,
- SCON, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- "ZP call CL\nZC", },
-
-{ STCALL, INAREG,
- SNAME|SAREG, TANY,
- SANY, TANY,
- NAREG|NASL, RESC1, /* should be 0 */
- "ZP call *AL\nZC", },
-
-/*
- * The next rules handle all binop-style operators.
- */
-/* Special treatment for long long */
-{ PLUS, INLL|FOREFF,
- SHLL, TLL,
- SHLL|SNAME|SOREG, TLL,
- 0, RLEFT,
- " addl AR,AL\n adcl UR,UL\n", },
-
-/* Special treatment for long long XXX - fix commutative check */
-{ PLUS, INLL|FOREFF,
- SHLL|SNAME|SOREG, TLL,
- SHLL, TLL,
- 0, RRIGHT,
- " addl AL,AR\n adcl UL,UR\n", },
-
-{ PLUS, INFL,
- SHFL, TDOUBLE,
- SNAME|SOREG, TDOUBLE,
- 0, RLEFT,
- " faddl AR\n", },
-
-{ PLUS, INFL|FOREFF,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- " faddp\n", },
-
-{ PLUS, INAREG,
- SAREG|SNAME|SOREG, TWORD|TPOINT,
- SONE, TANY,
- 0, RLEFT,
- " incl AL\n", },
-
-{ PLUS, INAREG,
- SAREG, TWORD|TPOINT,
- SCON, TANY,
- NAREG|NASL, RESC1,
- " leal CR(AL),A1\n", },
-
-{ PLUS, INCH,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SONE, TANY,
- 0, RLEFT,
- " incb AL\n", },
-
-{ PLUS, INAREG,
- SAREG, TWORD,
- SAREG, TWORD,
- NAREG|NASL|NASR, RESC1,
- " leal (AL,AR),A1\n", },
-
-
-/* address as register offset, negative */
-{ MINUS, INAREG,
- SAREG, TWORD|TPOINT,
- SPCON, TANY,
- NAREG|NASL, RESC1,
- " leal -CR(AL),A1\n", },
-
-{ MINUS, INLL|FOREFF,
- SHLL, TLL,
- SHLL|SNAME|SOREG, TLL,
- 0, RLEFT,
- " subl AR,AL\n sbbl UR,UL\n", },
-
-{ MINUS, INFL,
- SHFL, TDOUBLE,
- SNAME|SOREG, TDOUBLE,
- 0, RLEFT,
- " fsubl AR\n", },
-
-{ MINUS, INFL|FOREFF,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- " fsubZAp\n", },
-
-/* Simple r/m->reg ops */
-{ OPSIMP, INAREG|FOREFF,
- SAREG, TWORD|TPOINT,
- SAREG|SNAME|SOREG, TWORD|TPOINT,
- 0, RLEFT,
- " Ol AR,AL\n", },
-
-{ OPSIMP, INAREG|FOREFF,
- SHINT, TSHORT|TUSHORT,
- SHINT|SNAME|SOREG, TSHORT|TUSHORT,
- 0, RLEFT,
- " Ow AR,AL\n", },
-
-{ OPSIMP, INCH|FOREFF,
- SHCH, TCHAR|TUCHAR,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- 0, RLEFT,
- " Ob AR,AL\n", },
-
-{ OPSIMP, INAREG|FOREFF,
- SAREG, TWORD|TPOINT,
- SCON, TWORD|TPOINT,
- 0, RLEFT,
- " Ol AR,AL\n", },
-
-{ OPSIMP, INAREG|FOREFF,
- SHINT|SNAME|SOREG, TSHORT|TUSHORT,
- SCON, TANY,
- 0, RLEFT,
- " Ow AR,AL\n", },
-
-{ OPSIMP, INCH|FOREFF,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SCON, TANY,
- 0, RLEFT,
- " Ob AR,AL\n", },
-
-{ OPSIMP, INLL|FOREFF,
- SHLL, TLL,
- SHLL|SNAME|SOREG, TLL,
- 0, RLEFT,
- " Ol AR,AL\n Ol UR,UL\n", },
-
-
-/*
- * The next rules handle all shift operators.
- */
-/* (u)longlong left shift is emulated */
-{ LS, INCREG,
- SCREG|SNAME|SOREG|SCON, TLL,
- SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
- NSPECIAL|NCREG|NCSL|NCSR, RESC1,
- "ZO", },
-
-{ LS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TWORD,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " sall AR,AL\n", },
-
-{ LS, INAREG|FOREFF,
- SAREG, TWORD,
- SCON, TANY,
- 0, RLEFT,
- " sall AR,AL\n", },
-
-{ LS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " shlw AR,AL\n", },
-
-{ LS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- SCON, TANY,
- 0, RLEFT,
- " shlw AR,AL\n", },
-
-{ LS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " salb AR,AL\n", },
-
-{ LS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SCON, TANY,
- 0, RLEFT,
- " salb AR,AL\n", },
-
-/* (u)longlong right shift is emulated */
-{ RS, INCREG,
- SCREG|SNAME|SOREG|SCON, TLL,
- SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
- NSPECIAL|NCREG|NCSL|NCSR, RESC1,
- "ZO", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSWORD,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " sarl AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSWORD,
- SCON, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
- 0, RLEFT,
- " sarl AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TUWORD,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " shrl AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TUWORD,
- SCON, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
- 0, RLEFT,
- " shrl AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSHORT,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " sarw AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TSHORT,
- SCON, TANY,
- 0, RLEFT,
- " sarw AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TUSHORT,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " shrw AR,AL\n", },
-
-{ RS, INAREG|FOREFF,
- SAREG|SNAME|SOREG, TUSHORT,
- SCON, TANY,
- 0, RLEFT,
- " shrw AR,AL\n", },
-
-{ RS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TCHAR,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " sarb AR,AL\n", },
-
-{ RS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TCHAR,
- SCON, TANY,
- 0, RLEFT,
- " sarb AR,AL\n", },
-
-{ RS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TUCHAR,
- SHCH, TCHAR|TUCHAR,
- NSPECIAL, RLEFT,
- " shrb AR,AL\n", },
-
-{ RS, INCH|FOREFF,
- SHCH|SNAME|SOREG, TUCHAR,
- SCON, TANY,
- 0, RLEFT,
- " shrb AR,AL\n", },
-
-/*
- * The next rules takes care of assignments. "=".
- */
-{ ASSIGN, FOREFF,
- SHLL|SNAME|SOREG, TLL,
- SCON, TANY,
- 0, 0,
- " movl AR,AL\n movl UR,UL\n", },
-
-{ ASSIGN, FOREFF|INLL,
- SHLL, TLL,
- SCON, TANY,
- 0, RDEST,
- " movl AR,AL\n movl UR,UL\n", },
-
-{ ASSIGN, FOREFF,
- SAREG|SNAME|SOREG, TWORD|TPOINT,
- SCON, TANY,
- 0, 0,
- " movl AR,AL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SAREG, TWORD|TPOINT,
- SCON, TANY,
- 0, RDEST,
- " movl AR,AL\n", },
-
-{ ASSIGN, FOREFF,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- SCON, TANY,
- 0, 0,
- " movw AR,AL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SAREG, TSHORT|TUSHORT,
- SCON, TANY,
- 0, RDEST,
- " movw AR,AL\n", },
-
-{ ASSIGN, FOREFF,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SCON, TANY,
- 0, 0,
- " movb AR,AL\n", },
-
-{ ASSIGN, FOREFF|INCH,
- SHCH, TCHAR|TUCHAR,
- SCON, TANY,
- 0, RDEST,
- " movb AR,AL\n", },
-
-{ ASSIGN, FOREFF|INLL,
- SHLL|SNAME|SOREG, TLL,
- SHLL, TLL,
- 0, RDEST,
- " movl AR,AL\n movl UR,UL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SAREG|SNAME|SOREG, TWORD|TPOINT,
- SAREG, TWORD|TPOINT,
- 0, RDEST,
- " movl AR,AL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SAREG, TWORD|TPOINT,
- SAREG|SNAME|SOREG, TWORD|TPOINT,
- 0, RDEST,
- " movl AR,AL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- SAREG, TSHORT|TUSHORT,
- 0, RDEST,
- " movw AR,AL\n", },
-
-{ ASSIGN, FOREFF|INCH,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- SHCH, TCHAR|TUCHAR|TWORD,
- 0, RDEST,
- " movb AR,AL\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SFLD, TANY,
- SAREG, TANY,
- NAREG, RDEST,
- "ZE", },
-
-{ ASSIGN, FOREFF,
- SFLD, TANY,
- SAREG|SNAME|SOREG|SCON, TANY,
- NAREG, 0,
- "ZE", },
-
-{ ASSIGN, INDREG|FOREFF,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, RDEST,
- "", }, /* This will always be in the correct register */
-
-/* order of table entries is very important here! */
-{ ASSIGN, INFL,
- SNAME|SOREG, TLDOUBLE,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, RDEST,
- " fstt AL\n", },
-
-{ ASSIGN, FOREFF,
- SNAME|SOREG, TLDOUBLE,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, 0,
- " fstpt AL\n", },
-
-{ ASSIGN, INFL,
- SNAME|SOREG, TDOUBLE,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, RDEST,
- " fstl AL\n", },
-
-{ ASSIGN, FOREFF,
- SNAME|SOREG, TDOUBLE,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, 0,
- " fstpl AL\n", },
-
-{ ASSIGN, INFL,
- SNAME|SOREG, TFLOAT,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, RDEST,
- " fsts AL\n", },
-
-{ ASSIGN, FOREFF,
- SNAME|SOREG, TFLOAT,
- SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
- 0, 0,
- " fstps AL\n", },
-/* end very important order */
-
-{ ASSIGN, INFL|FOREFF,
- SHFL, TLDOUBLE,
- SHFL|SOREG|SNAME, TLDOUBLE,
- 0, RDEST,
- " fldt AR\n", },
-
-{ ASSIGN, INFL|FOREFF,
- SHFL, TDOUBLE,
- SHFL|SOREG|SNAME, TDOUBLE,
- 0, RDEST,
- " fldl AR\n", },
-
-{ ASSIGN, INFL|FOREFF,
- SHFL, TFLOAT,
- SHFL|SOREG|SNAME, TFLOAT,
- 0, RDEST,
- " flds AR\n", },
-
-/* Do not generate memcpy if return from funcall */
-#if 0
-{ STASG, INAREG|FOREFF,
- SOREG|SNAME|SAREG, TPTRTO|TSTRUCT,
- SFUNCALL, TPTRTO|TSTRUCT,
- 0, RRIGHT,
- "", },
-#endif
-
-{ STASG, INAREG|FOREFF,
- SOREG|SNAME, TANY,
- SAREG|SOREG|SNAME, TPTRTO|TANY,
- NSPECIAL, RRIGHT,
- "ZQ", },
-
-/*
- * DIV/MOD/MUL
- */
-/* long long div is emulated */
-{ DIV, INCREG,
- SCREG|SNAME|SOREG|SCON, TLL,
- SCREG|SNAME|SOREG|SCON, TLL,
- NSPECIAL|NCREG|NCSL|NCSR, RESC1,
- "ZO", },
-
-{ DIV, INAREG,
- SAREG, TSWORD,
- SAREG|SNAME|SOREG, TWORD,
- NSPECIAL, RDEST,
- " cltd\n idivl AR\n", },
-
-{ DIV, INAREG,
- SAREG, TUWORD|TPOINT,
- SAREG|SNAME|SOREG, TUWORD|TPOINT,
- NSPECIAL, RDEST,
- " xorl %edx,%edx\n divl AR\n", },
-
-{ DIV, INAREG,
- SAREG, TUSHORT,
- SAREG|SNAME|SOREG, TUSHORT,
- NSPECIAL, RDEST,
- " xorl %edx,%edx\n divw AR\n", },
-
-{ DIV, INCH,
- SHCH, TUCHAR,
- SHCH|SNAME|SOREG, TUCHAR,
- NSPECIAL, RDEST,
- " xorb %ah,%ah\n divb AR\n", },
-
-{ DIV, INFL,
- SHFL, TDOUBLE,
- SNAME|SOREG, TDOUBLE,
- 0, RLEFT,
- " fdivl AR\n", },
-
-{ DIV, INFL,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- " fdivZAp\n", },
-
-/* (u)longlong mod is emulated */
-{ MOD, INCREG,
- SCREG|SNAME|SOREG|SCON, TLL,
- SCREG|SNAME|SOREG|SCON, TLL,
- NSPECIAL|NCREG|NCSL|NCSR, RESC1,
- "ZO", },
-
-{ MOD, INAREG,
- SAREG, TSWORD,
- SAREG|SNAME|SOREG, TSWORD,
- NAREG|NSPECIAL, RESC1,
- " cltd\n idivl AR\n", },
-
-{ MOD, INAREG,
- SAREG, TUWORD|TPOINT,
- SAREG|SNAME|SOREG, TUWORD|TPOINT,
- NAREG|NSPECIAL, RESC1,
- " xorl %edx,%edx\n divl AR\n", },
-
-{ MOD, INAREG,
- SAREG, TUSHORT,
- SAREG|SNAME|SOREG, TUSHORT,
- NAREG|NSPECIAL, RESC1,
- " xorl %edx,%edx\n divw AR\n", },
-
-{ MOD, INCH,
- SHCH, TUCHAR,
- SHCH|SNAME|SOREG, TUCHAR,
- NBREG|NSPECIAL, RESC1,
- " xorb %ah,%ah\n divb AR\n", },
-
-/* (u)longlong mul is emulated */
-{ MUL, INCREG,
- SCREG|SNAME|SOREG|SCON, TLL,
- SCREG|SNAME|SOREG|SCON, TLL,
- NSPECIAL|NCREG|NCSL|NCSR, RESC1,
- "ZO", },
-
-{ MUL, INAREG,
- SAREG, TWORD|TPOINT,
- SAREG|SNAME|SOREG|SCON, TWORD|TPOINT,
- 0, RLEFT,
- " imull AR,AL\n", },
-
-{ MUL, INAREG,
- SAREG, TSHORT|TUSHORT,
- SAREG|SNAME|SOREG, TSHORT|TUSHORT,
- 0, RLEFT,
- " imulw AR,AL\n", },
-
-{ MUL, INCH,
- SHCH, TCHAR|TUCHAR,
- SHCH|SNAME|SOREG, TCHAR|TUCHAR,
- NSPECIAL, RDEST,
- " imulb AR\n", },
-
-{ MUL, INFL,
- SHFL, TDOUBLE,
- SNAME|SOREG, TDOUBLE,
- 0, RLEFT,
- " fmull AR\n", },
-
-{ MUL, INFL,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- " fmulp\n", },
-
-/*
- * Indirection operators.
- */
-{ UMUL, INLL,
- SANY, TANY,
- SOREG, TLL,
- NCREG|NCSL, RESC1,
- " movl UL,U1\n movl AL,A1\n", },
-
-{ UMUL, INAREG,
- SANY, TPOINT|TWORD,
- SOREG, TPOINT|TWORD,
- NAREG|NASL, RESC1,
- " movl AL,A1\n", },
-
-{ UMUL, INCH,
- SANY, TANY,
- SOREG, TCHAR|TUCHAR,
- NBREG|NBSL, RESC1,
- " movb AL,A1\n", },
-
-{ UMUL, INAREG,
- SANY, TANY,
- SOREG, TSHORT|TUSHORT,
- NAREG|NASL, RESC1,
- " movw AL,A1\n", },
-
-{ UMUL, INFL,
- SANY, TANY,
- SOREG, TLDOUBLE,
- NDREG|NDSL, RESC1,
- " fldt AL\n", },
-
-{ UMUL, INFL,
- SANY, TANY,
- SOREG, TDOUBLE,
- NDREG|NDSL, RESC1,
- " fldl AL\n", },
-
-{ UMUL, INFL,
- SANY, TANY,
- SOREG, TFLOAT,
- NDREG|NDSL, RESC1,
- " flds AL\n", },
-
-/*
- * Logical/branching operators
- */
-
-/* Comparisions, take care of everything */
-{ OPLOG, FORCC,
- SHLL|SOREG|SNAME, TLL,
- SHLL, TLL,
- 0, 0,
- "ZD", },
-
-{ OPLOG, FORCC,
- SAREG|SOREG|SNAME, TWORD|TPOINT,
- SCON|SAREG, TWORD|TPOINT,
- 0, RESCC,
- " cmpl AR,AL\n", },
-
-{ OPLOG, FORCC,
- SCON|SAREG, TWORD|TPOINT,
- SAREG|SOREG|SNAME, TWORD|TPOINT,
- 0, RESCC,
- " cmpl AR,AL\n", },
-
-{ OPLOG, FORCC,
- SAREG|SOREG|SNAME, TSHORT|TUSHORT,
- SCON|SAREG, TANY,
- 0, RESCC,
- " cmpw AR,AL\n", },
-
-{ OPLOG, FORCC,
- SBREG|SOREG|SNAME, TCHAR|TUCHAR,
- SCON|SBREG, TANY,
- 0, RESCC,
- " cmpb AR,AL\n", },
-
-{ OPLOG, FORCC,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- NSPECIAL, 0,
- "ZG", },
-
-{ OPLOG, FORCC,
- SOREG|SNAME, TDOUBLE|TFLOAT,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- NSPECIAL, 0,
- "ZG", },
-
-#if 0
-/* Ppro and later only */
-{ OPLOG, FORCC,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RESCC,
- "ZA fucomip %st,%st(1)\n", },
-#endif
-
-{ OPLOG, FORCC,
- SANY, TANY,
- SANY, TANY,
- REWRITE, 0,
- "diediedie!", },
-
-/* AND/OR/ER/NOT */
-{ AND, INAREG|FOREFF,
- SAREG|SOREG|SNAME, TWORD,
- SCON|SAREG, TWORD,
- 0, RLEFT,
- " andl AR,AL\n", },
-
-{ AND, INCREG|FOREFF,
- SCREG, TLL,
- SCREG|SOREG|SNAME, TLL,
- 0, RLEFT,
- " andl AR,AL\n andl UR,UL\n", },
-
-{ AND, INAREG|FOREFF,
- SAREG, TWORD,
- SAREG|SOREG|SNAME, TWORD,
- 0, RLEFT,
- " andl AR,AL\n", },
-
-{ AND, INAREG|FOREFF,
- SAREG|SOREG|SNAME, TSHORT|TUSHORT,
- SCON|SAREG, TSHORT|TUSHORT,
- 0, RLEFT,
- " andw AR,AL\n", },
-
-{ AND, INAREG|FOREFF,
- SAREG, TSHORT|TUSHORT,
- SAREG|SOREG|SNAME, TSHORT|TUSHORT,
- 0, RLEFT,
- " andw AR,AL\n", },
-
-{ AND, INBREG|FOREFF,
- SBREG|SOREG|SNAME, TCHAR|TUCHAR,
- SCON|SBREG, TCHAR|TUCHAR,
- 0, RLEFT,
- " andb AR,AL\n", },
-
-{ AND, INBREG|FOREFF,
- SBREG, TCHAR|TUCHAR,
- SBREG|SOREG|SNAME, TCHAR|TUCHAR,
- 0, RLEFT,
- " andb AR,AL\n", },
-/* AND/OR/ER/NOT */
-
-/*
- * Jumps.
- */
-{ GOTO, FOREFF,
- SCON, TANY,
- SANY, TANY,
- 0, RNOP,
- " jmp LL\n", },
-
-#ifdef GCC_COMPAT
-{ GOTO, FOREFF,
- SAREG, TANY,
SANY, TANY,
0, RNOP,
- " jmp *AL\n", },
-#endif
-
-/*
- * Convert LTYPE to reg.
- */
-{ OPLTYPE, INLL,
- SANY, TANY,
- SCREG|SCON|SOREG|SNAME, TLL,
- NCREG, RESC1,
- " movl UL,U1\n movl AL,A1\n", },
-
-{ OPLTYPE, INAREG,
- SANY, TANY,
- SAREG|SCON|SOREG|SNAME, TWORD|TPOINT,
- NAREG|NASL, RESC1,
- " movl AL,A1\n", },
-
-{ OPLTYPE, INBREG,
- SANY, TANY,
- SBREG|SOREG|SNAME|SCON, TCHAR|TUCHAR,
- NBREG, RESC1,
- " movb AL,A1\n", },
-
-{ OPLTYPE, INAREG,
- SANY, TANY,
- SAREG|SOREG|SNAME|SCON, TSHORT|TUSHORT,
- NAREG, RESC1,
- " movw AL,A1\n", },
-
-{ OPLTYPE, INDREG,
- SANY, TLDOUBLE,
- SOREG|SNAME, TLDOUBLE,
- NDREG, RESC1,
- " fldt AL\n", },
-
-{ OPLTYPE, INDREG,
- SANY, TDOUBLE,
- SOREG|SNAME, TDOUBLE,
- NDREG, RESC1,
- " fldl AL\n", },
-
-{ OPLTYPE, INDREG,
- SANY, TFLOAT,
- SOREG|SNAME, TFLOAT,
- NDREG, RESC1,
- " flds AL\n", },
-
-/* Only used in ?: constructs. The stack already contains correct value */
-{ OPLTYPE, INDREG,
- SANY, TFLOAT|TDOUBLE|TLDOUBLE,
- SDREG, TFLOAT|TDOUBLE|TLDOUBLE,
- NDREG, RESC1,
- "", },
-
-/*
- * Negate a word.
- */
-
-{ UMINUS, INCREG|FOREFF,
- SCREG, TLL,
- SCREG, TLL,
- 0, RLEFT,
- " negl AL\n adcl $0,UL\n negl UL\n", },
-
-{ UMINUS, INAREG|FOREFF,
- SAREG, TWORD|TPOINT,
- SAREG, TWORD|TPOINT,
- 0, RLEFT,
- " negl AL\n", },
-
-{ UMINUS, INAREG|FOREFF,
- SAREG, TSHORT|TUSHORT,
- SAREG, TSHORT|TUSHORT,
- 0, RLEFT,
- " negw AL\n", },
-
-{ UMINUS, INBREG|FOREFF,
- SBREG, TCHAR|TUCHAR,
- SBREG, TCHAR|TUCHAR,
- 0, RLEFT,
- " negb AL\n", },
-
-{ UMINUS, INFL|FOREFF,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
- 0, RLEFT,
- " fchs\n", },
-
-{ COMPL, INCREG,
- SCREG, TLL,
- SANY, TANY,
- 0, RLEFT,
- " notl AL\n notl UL\n", },
-
-{ COMPL, INAREG,
- SAREG, TWORD,
- SANY, TANY,
- 0, RLEFT,
- " notl AL\n", },
-
-{ COMPL, INAREG,
- SAREG, TSHORT|TUSHORT,
- SANY, TANY,
- 0, RLEFT,
- " notw AL\n", },
-
-{ COMPL, INBREG,
- SBREG, TCHAR|TUCHAR,
- SANY, TANY,
- 0, RLEFT,
- " notb AL\n", },
-
-/*
- * Arguments to functions.
- */
-{ FUNARG, FOREFF,
- SCON|SCREG|SNAME|SOREG, TLL,
- SANY, TLL,
- 0, RNULL,
- " pushl UL\n pushl AL\n", },
-#endif
+ " jmp @LL\n", },
{ FUNARG, FOREFF,
SAREG|SBREG, TCHAR|TUCHAR|TWORD|TPOINT,
SANY, TCHAR|TUCHAR|TWORD|TPOINT,
- 0, RNULL,
- " sta AL,@sp\n", },
-
-#if 0
-{ FUNARG, FOREFF,
- SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- SANY, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- 0, RNULL,
- " pushl AL\n", },
-
-{ FUNARG, FOREFF,
- SAREG|SNAME|SOREG, TSHORT,
- SANY, TSHORT,
- NAREG, 0,
- " movswl AL,ZN\n pushl ZN\n", },
-
-{ FUNARG, FOREFF,
- SAREG|SNAME|SOREG, TUSHORT,
- SANY, TUSHORT,
- NAREG, 0,
- " movzwl AL,ZN\n pushl ZN\n", },
-
-{ FUNARG, FOREFF,
- SHCH|SNAME|SOREG, TCHAR,
- SANY, TCHAR,
- NAREG, 0,
- " movsbl AL,A1\n pushl A1\n", },
-
-{ FUNARG, FOREFF,
- SHCH|SNAME|SOREG, TUCHAR,
- SANY, TUCHAR,
- NAREG, 0,
- " movzbl AL,A1\n pushl A1\n", },
-
-{ FUNARG, FOREFF,
- SNAME|SOREG, TDOUBLE,
- SANY, TDOUBLE,
- 0, 0,
- " pushl UL\n pushl AL\n", },
-
-{ FUNARG, FOREFF,
- SDREG, TDOUBLE,
- SANY, TDOUBLE,
- 0, 0,
- " subl $8,%esp\n fstpl (%esp)\n", },
-
-{ FUNARG, FOREFF,
- SNAME|SOREG, TFLOAT,
- SANY, TFLOAT,
- 0, 0,
- " pushl AL\n", },
-
-{ FUNARG, FOREFF,
- SDREG, TFLOAT,
- SANY, TFLOAT,
- 0, 0,
- " subl $4,%esp\n fstps (%esp)\n", },
-
-{ FUNARG, FOREFF,
- SDREG, TLDOUBLE,
- SANY, TLDOUBLE,
- 0, 0,
- " subl $12,%esp\n fstpt (%esp)\n", },
-
-{ STARG, FOREFF,
- SAREG|SOREG|SNAME|SCON, TANY,
- SANY, TSTRUCT,
- NSPECIAL|NAREG, 0,
- "ZF", },
-
-#endif
+ NBREG, RNULL,
+ " lda A1,csp\n sta AL,ZB\n", },
# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
-/* $Id: code.c,v 1.31 2014/05/29 19:20:03 plunky Exp $ */
+/* $Id: code.c,v 1.32 2016/07/10 09:49:52 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
#include "pass1.h"
#include "pass2.h"
+#ifdef LANG_CXX
+#define p1listf listf
+#define p1tfree tfree
+#define p1nfree nfree
+#define p1tcopy tcopy
+#else
+#define NODE P1ND
+#define talloc p1alloc
+#endif
+
static void genswitch_bintree(int num, TWORD ty, struct swents **p, int n);
#if 0
{
char *name;
- name = sp->soname ? sp->soname : exname(sp->sname);
+ name = getexname(sp);
if (sp->sclass == EXTDEF)
printf(" .globl %s\n", name);
if (sp->slevel == 0)
q = pusharg(p, regp);
} else if (reg == R10) {
/* half in and half out of the registers */
- r = tcopy(p);
+ r = p1tcopy(p);
if (!features(FEATURE_BIGENDIAN)) {
q = block(SCONV, p, NIL, INT, 0, 0);
q = movearg_32bit(q, regp); /* little-endian */
/* remove STARG node */
l = p->n_left;
- nfree(p);
+ p1nfree(p);
ty = l->n_type;
/*
-/* $Id: local.c,v 1.34 2012/09/06 13:07:29 plunky Exp $ */
+/* $Id: local.c,v 1.35 2016/07/10 09:49:52 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
#include <assert.h>
#include "pass1.h"
+#undef NIL
+#define NIL NULL
+
+#ifdef LANG_CXX
+#define P1ND NODE
+#define p1nfree nfree
+#define p1tfree tfree
+#define p1fwalk fwalk
+#define p1walkf walkf
+#define p1tcopy tcopy
+#else
+#define NODE P1ND
+#define nfree p1nfree
+#endif
+
#define IALLOC(sz) (isinlining ? permalloc(sz) : tmpalloc(sz))
extern int kflag;
struct symtab *sp = IALLOC(sizeof(struct symtab));
size_t len = strlen(p) + strlen(s) + strlen(s2) + 1;
- sp->sname = sp->soname = IALLOC(len);
- strlcpy(sp->soname, p, len);
- strlcat(sp->soname, s, len);
- strlcat(sp->soname, s2, len);
+ sp->sname = IALLOC(len);
+ strlcpy(sp->sname, p, len);
+ strlcat(sp->sname, s, len);
+ strlcat(sp->sname, s2, len);
sp->sclass = EXTERN;
sp->sflags = sp->slevel = 0;
struct symtab *sp;
char *name;
- name = p->n_sp->soname ? p->n_sp->soname : exname(p->n_sp->sname);
+ name = getexname(p->n_sp);
if (strncmp(name, "__builtin", 9) == 0)
return p;
q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
q->n_sp = p->n_sp; /* for init */
- nfree(p);
+ p1nfree(p);
return q;
}
snprintf(buf, 64, LABFMT, (int)p->n_sp->soffset);
sp = picsymtab("", buf, "@got(31)");
} else {
- n = p->n_sp->soname ? p->n_sp->soname : p->n_sp->sname;
- sp = picsymtab("", exname(n), "@got(31)");
+ n = getexname(p->n_sp);
+ sp = picsymtab("", n, "@got(31)");
}
sp->sclass = STATIC;
sp->stype = p->n_sp->stype;
q = xbcon(0, sp, PTR+VOID);
q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
q->n_sp = p->n_sp;
- nfree(p);
+ p1nfree(p);
#elif defined(MACHOABI)
q = block(SCONV, q, NIL, LONGLONG, 0, 0);
q = block(SCONV, q, NIL, ty, 0, 0);
t = block(FCON, NIL, NIL, ty, 0, 0);
- t->n_dcon = 2;
+ t->n_dcon = fltallo();
+ FCAST(t->n_dcon)->fp = 2.0;
l = block(MUL, q, t, ty, 0, 0);
r = buildtree(COLON, l, r);
#ifdef PCC_DEBUG
if (xdebug) {
printf("clocal: %p\n", p);
- fwalk(p, eprint, 0);
+ p1fwalk(p, eprint, 0);
}
#endif
switch (o = p->n_op) {
case AUTO:
/* fake up a structure reference */
r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
- r->n_lval = 0;
+ slval(r, 0);
r->n_rval = FPREG;
p = stref(block(STREF, r, p, 0, 0, 0));
break;
if (kflag == 0) {
if (q->slevel == 0)
break;
- p->n_lval = 0;
+ slval(p, 0);
} else if (blevel > 0) {
p = picstatic(p);
}
case REGISTER:
p->n_op = REG;
- p->n_lval = 0;
+ slval(p, 0);
p->n_rval = q->soffset;
break;
/* Remove redundant PCONV's. Be careful */
l = p->n_left;
if (l->n_op == ICON) {
- l->n_lval = (unsigned)l->n_lval;
+ slval(l, (unsigned)glval(l));
goto delp;
}
if (l->n_type < INT || DEUNSIGN(l->n_type) == LONGLONG) {
m = p->n_type;
if (o == ICON) {
- CONSZ val = l->n_lval;
+ CONSZ val = glval(l);
if (!ISPTR(m)) /* Pointers don't need to be conv'd */
switch (m) {
case BOOL:
- l->n_lval = l->n_lval != 0;
+ slval(l, val != 0);
break;
case CHAR:
- l->n_lval = (char)val;
+ slval(l, (char)val);
break;
case UCHAR:
- l->n_lval = val & 0377;
+ slval(l, val & 0377);
break;
case SHORT:
- l->n_lval = (short)val;
+ slval(l, (short)val);
break;
case USHORT:
- l->n_lval = val & 0177777;
+ slval(l, val & 0177777);
break;
case ULONG:
case UNSIGNED:
- l->n_lval = val & 0xffffffff;
+ slval(l, val & 0xffffffff);
break;
case LONG:
case INT:
- l->n_lval = (int)val;
+ slval(l, (int)val);
break;
case LONGLONG:
- l->n_lval = (long long)val;
+ slval(l, (long long)val);
break;
case ULONGLONG:
- l->n_lval = val;
+ slval(l, val);
break;
case VOID:
break;
case DOUBLE:
case FLOAT:
l->n_op = FCON;
- l->n_dcon = val;
+ l->n_dcon = fltallo();
+ FCAST(l->n_dcon)->fp = val;
break;
default:
cerror("unknown type %d", m);
nfree(p);
return l;
} else if (o == FCON) {
- l->n_lval = l->n_dcon;
+ slval(l, FCAST(l->n_dcon)->fp);
l->n_sp = NULL;
l->n_op = ICON;
l->n_type = m;
#ifdef PCC_DEBUG
if (xdebug) {
printf("clocal end: %p\n", p);
- fwalk(p, eprint, 0);
+ p1fwalk(p, eprint, 0);
}
#endif
return(p);
fixnames(NODE *p, void *arg)
{
struct symtab *sp;
- struct attr *ap;
+ struct attr *ap, *ap2;
NODE *q;
char *c;
int isu;
c = NULL;
#if defined(ELFABI)
- if (sp->soname == NULL ||
- (c = strstr(sp->soname, "@got(31)")) == NULL)
+ if ((ap2 = attr_find(sp->sap, ATTR_SONAME)) == NULL ||
+ (c = strstr(ap2->sarg(0), "@got(31)")) == NULL)
cerror("fixnames2");
if (isu) {
memcpy(c, "@plt", sizeof("@plt"));
struct symtab *sp;
if (kflag)
- walkf(p, fixnames, 0);
+ p1walkf(p, fixnames, 0);
if (o != FCON)
return;
ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);
p->n_op = NAME;
- p->n_lval = 0;
+ slval(p, 0);
p->n_sp = sp;
}
{
union { float f; double d; long double l; int i[3]; } u;
struct symtab *q;
- char *c;
TWORD t;
int i;
if (t > BTMASK)
p->n_type = t = INT; /* pointer */
-
+#if 0 /* not needed anymore */
if (kflag && (p->n_op == PLUS || p->n_op == UMUL)) {
+ char *c;
if (p->n_op == UMUL)
p = p->n_left;
p = p->n_right;
#endif
}
+#endif
if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
uerror("element not constant");
case ULONGLONG:
#if 0
/* little-endian */
- i = (p->n_lval >> 32);
- p->n_lval &= 0xffffffff;
+ i = (glval(p) >> 32);
+ slval(p, glval(p) & 0xffffffff);
p->n_type = INT;
ninval(off, 32, p);
- p->n_lval = i;
+ slval(p, i);
ninval(off+32, 32, p);
#endif
/* big-endian */
- i = (p->n_lval & 0xffffffff);
- p->n_lval >>= 32;
+ i = (glval(p) & 0xffffffff);
+ slval(p, glval(p) >> 32);
p->n_type = INT;
ninval(off, 32, p);
- p->n_lval = i;
+ slval(p, i);
ninval(off+32, 32, p);
break;
case INT:
case UNSIGNED:
- printf("\t.long %d", (int)p->n_lval);
+ printf("\t.long %d", (int)glval(p));
if ((q = p->n_sp) != NULL) {
if ((q->sclass == STATIC && q->slevel > 0)) {
printf("+" LABFMT, q->soffset);
} else {
- char *name = q->soname ? q->soname : exname(q->sname);
+ char *name = getexname(q);
printf("+%s", name);
}
}
break;
case LDOUBLE:
u.i[2] = 0;
- u.l = (long double)p->n_dcon;
+ u.l = (long double)FCAST(p->n_dcon)->fp;
#if 0
/* little-endian */
printf("\t.long 0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
printf("\t.long 0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]);
break;
case DOUBLE:
- u.d = (double)p->n_dcon;
+ u.d = (double)FCAST(p->n_dcon)->fp;
printf("\t.long 0x%x\n\t.long 0x%x\n", u.i[0], u.i[1]);
break;
case FLOAT:
- u.f = (float)p->n_dcon;
+ u.f = (float)FCAST(p->n_dcon)->fp;
printf("\t.long 0x%x\n", u.i[0]);
break;
default:
off = tsize(sp->stype, sp->sdf, sp->sap);
off = (off+(SZCHAR-1))/SZCHAR;
printf("\t.%scomm ", sp->sclass == STATIC ? "l" : "");
- n = sp->soname ? sp->soname : exname(sp->sname);
+ n = getexname(sp);
if (sp->slevel == 0)
printf("%s,%d\n", n, off);
else
off = tsize(q->stype, q->sdf, q->ssue);
off = (off+(SZCHAR-1))/SZCHAR;
- printf("\t.comm %s,0%o\n", q->soname ? q->soname : exname(q->sname), off);
+ printf("\t.comm %s,0%o\n", getexname(q), off);
}
/* make a local common declaration for id, if reasonable */
off = tsize(q->stype, q->sdf, q->ssue);
off = (off+(SZCHAR-1))/SZCHAR;
if (q->slevel == 0)
- printf("\t.lcomm %s,%d\n", q->soname ? q->soname : exname(q->sname), off);
+ printf("\t.lcomm %s,%d\n", getexname(q), off);
else
printf("\t.lcomm " LABFMT ",%d\n", q->soffset, off);
}
#define ISPOW2(n) ((n) && (((n)&((n)-1)) == 0))
/* if the right is a constant power of two, then replace with AND */
- if (r->n_op == ICON && ISPOW2(r->n_lval)) {
+ if (r->n_op == ICON && ISPOW2(glval(r))) {
p->n_op = AND;
- r->n_lval--;
+ slval(r, glval(r) - 1);
return;
}
*/
NODE *
-powerpc_builtin_stdarg_start(NODE *f, NODE *a, TWORD t)
+powerpc_builtin_stdarg_start(const struct bitable *bi, NODE *a)
{
NODE *p, *q;
int sz = 1;
- /* check num args and type */
- if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
- !ISPTR(a->n_left->n_type))
- goto bad;
-
/* must first deal with argument size; use int size */
p = a->n_right;
if (p->n_type < INT) {
nfree(q->n_left);
nfree(q);
p = buildtree(ASSIGN, a->n_left, p);
- tfree(f);
nfree(a);
return p;
-
-bad:
- uerror("bad argument to __builtin_stdarg_start");
- return bcon(0);
}
NODE *
-powerpc_builtin_va_arg(NODE *f, NODE *a, TWORD t)
+powerpc_builtin_va_arg(const struct bitable *bi, NODE *a)
{
NODE *p, *q, *r;
int sz, tmpnr;
- /* check num args and type */
- if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
- !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE)
- goto bad;
-
r = a->n_right;
/* get type size */
r->n_ap = 0;
}
- p = tcopy(a->n_left);
+ p = p1tcopy(a->n_left);
#if defined(ELFABI)
nfree(a->n_right);
nfree(a);
- nfree(f);
p = tempnode(tmpnr, INCREF(r->n_type), r->n_df, r->n_ap);
p = buildtree(UMUL, p, NIL);
p = buildtree(COMOP, q, p);
return p;
-
-bad:
- uerror("bad argument to __builtin_va_arg");
- return bcon(0);
}
NODE *
-powerpc_builtin_va_end(NODE *f, NODE *a, TWORD t)
+powerpc_builtin_va_end(const struct bitable *bi, NODE *a)
{
- tfree(f);
- tfree(a);
-
+ p1tfree(a);
return bcon(0);
}
NODE *
-powerpc_builtin_va_copy(NODE *f, NODE *a, TWORD t)
+powerpc_builtin_va_copy(const struct bitable *bi, NODE *a)
{
- if (a == NULL || a->n_op != CM || a->n_left->n_op == CM)
- goto bad;
- tfree(f);
- f = buildtree(ASSIGN, a->n_left, a->n_right);
- nfree(a);
+ P1ND *f = buildtree(ASSIGN, a->n_left, a->n_right);
+ p1nfree(a);
return f;
-
-bad:
- uerror("bad argument to __buildtin_va_copy");
- return bcon(0);
}
NODE *
-powerpc_builtin_return_address(NODE *f, NODE *a, TWORD t)
+builtin_return_address(const struct bitable *bt, NODE *a)
{
+ P1ND *f;
int nframes;
int i = 0;
- if (a == NULL || a->n_op != ICON)
- goto bad;
+ nframes = glval(a);
- nframes = a->n_lval;
-
- tfree(f);
- tfree(a);
+ p1tfree(a);
f = block(REG, NIL, NIL, PTR+VOID, 0, 0);
regno(f) = SPREG;
f = buildtree(UMUL, f, NIL);
return f;
-bad:
- uerror("bad argument to __builtin_return_address");
- return bcon(0);
}
NODE *
-powerpc_builtin_frame_address(NODE *f, NODE *a, TWORD t)
+builtin_frame_address(const struct bitable *bt, NODE *a)
{
+ P1ND *f;
int nframes;
int i = 0;
- if (a == NULL || a->n_op != ICON)
- goto bad;
-
- nframes = a->n_lval;
+ nframes = glval(a);
- tfree(f);
- tfree(a);
+ p1tfree(a);
if (nframes == 0) {
f = block(REG, NIL, NIL, PTR+VOID, 0, 0);
}
return f;
-bad:
- uerror("bad argument to __builtin_frame_address");
+}
+
+/*
+ * Return "canonical frame address".
+ */
+NODE *
+builtin_cfa(const struct bitable *bt, NODE *a)
+{
+ cerror("builtin_cfa");
return bcon(0);
}
+
void
pass1_lastchance(struct interpass *ip)
{
-/* $Id: local2.c,v 1.28 2015/01/04 19:17:23 ragge Exp $ */
+/* $Id: local2.c,v 1.29 2016/07/10 09:49:52 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
NODE *r = p->n_right;
TWORD ty = p->n_type;
- if (p->n_op == LS && r->n_op == ICON && r->n_lval < 32) {
+ if (p->n_op == LS && r->n_op == ICON && getlval(r) < 32) {
expand(p, INBREG, "\tsrwi A1,AL,32-AR" COM "64-bit left-shift\n");
expand(p, INBREG, "\tslwi U1,UL,AR\n");
expand(p, INBREG, "\tor U1,U1,A1\n");
expand(p, INBREG, "\tslwi A1,AL,AR\n");
- } else if (p->n_op == LS && r->n_op == ICON && r->n_lval < 64) {
+ } else if (p->n_op == LS && r->n_op == ICON && getlval(r) < 64) {
expand(p, INBREG, "\tli A1,0" COM "64-bit left-shift\n");
- if (r->n_lval == 32)
+ if (getlval(r) == 32)
expand(p, INBREG, "\tmr U1,AL\n");
else
expand(p, INBREG, "\tslwi U1,AL,AR-32\n");
} else if (p->n_op == LS && r->n_op == ICON) {
expand(p, INBREG, "\tli A1,0" COM "64-bit left-shift\n");
expand(p, INBREG, "\tli U1,0\n");
- } else if (p->n_op == RS && r->n_op == ICON && r->n_lval < 32) {
+ } else if (p->n_op == RS && r->n_op == ICON && getlval(r) < 32) {
expand(p, INBREG, "\tslwi U1,UL,32-AR" COM "64-bit right-shift\n");
expand(p, INBREG, "\tsrwi A1,AL,AR\n");
expand(p, INBREG, "\tor A1,A1,U1\n");
expand(p, INBREG, "\tsrawi U1,UL,AR\n");
else
expand(p, INBREG, "\tsrwi U1,UL,AR\n");
- } else if (p->n_op == RS && r->n_op == ICON && r->n_lval < 64) {
+ } else if (p->n_op == RS && r->n_op == ICON && getlval(r) < 64) {
if (ty == LONGLONG)
expand(p, INBREG, "\tli U1,-1" COM "64-bit right-shift\n");
else
expand(p, INBREG, "\tli U1,0" COM "64-bit right-shift\n");
- if (r->n_lval == 32)
+ if (getlval(r) == 32)
expand(p, INBREG, "\tmr A1,UL\n");
else if (ty == LONGLONG)
expand(p, INBREG, "\tsrawi A1,UL,AR-32\n");
stasg(NODE *p)
{
NODE *l = p->n_left;
- int val = l->n_lval;
+ int val = getlval(l);
/* R3 = dest, R4 = src, R5 = len */
printf("\tli %s,%d\n", rnames[R5], attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0));
void
conput(FILE *fp, NODE *p)
{
- int val = p->n_lval;
+ int val = getlval(p);
switch (p->n_op) {
case ICON:
fprintf(fp, "+%d", val);
} else {
if (GCLASS(p->n_type) == CLASSB)
- fprintf(fp, CONFMT, p->n_lval >> 32);
+ fprintf(fp, CONFMT, getlval(p) >> 32);
else
fprintf(fp, "%d", val);
}
case NAME:
case OREG:
if (features(FEATURE_BIGENDIAN))
- printf("%d", (int)p->n_lval);
+ printf("%d", (int)getlval(p));
else
- printf("%d", (int)(p->n_lval + 4));
+ printf("%d", (int)(getlval(p) + 4));
printf("(%s)", rnames[regno(p)]);
break;
case ICON:
- printf(CONFMT, p->n_lval >> 32);
+ printf(CONFMT, getlval(p) >> 32);
break;
default:
case NAME:
if (p->n_name[0] != '\0') {
fputs(p->n_name, io);
- if (p->n_lval != 0)
- fprintf(io, "+" CONFMT, p->n_lval);
+ if (getlval(p) != 0)
+ fprintf(io, "+" CONFMT, getlval(p));
} else
- fprintf(io, CONFMT, p->n_lval);
+ fprintf(io, CONFMT, getlval(p));
return;
case OREG:
if (DEUNSIGN(p->n_type) == LONGLONG &&
features(FEATURE_BIGENDIAN))
- fprintf(io, "%d", (int)(p->n_lval + 4));
+ fprintf(io, "%d", (int)getlval(p) + 4);
else
- fprintf(io, "%d", (int)p->n_lval);
+ fprintf(io, "%d", (int)getlval(p));
fprintf(io, "(%s)", rnames[regno(p)]);
return;
return SRREG;
break;
case SPCON:
- if (o == ICON && p->n_name[0] == 0 && (p->n_lval & ~0x7fff) == 0)
+ if (o == ICON && p->n_name[0] == 0 && (getlval(p) & ~0x7fff) == 0)
return SRDIR;
break;
}
-/* $Id: macdefs.h,v 1.18 2016/03/05 15:53:04 ragge Exp $ */
+/* $Id: macdefs.h,v 1.19 2016/07/10 09:49:52 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
#define TARGET_STDARGS
#define TARGET_BUILTINS \
- { "__builtin_stdarg_start", powerpc_builtin_stdarg_start }, \
- { "__builtin_va_arg", powerpc_builtin_va_arg }, \
- { "__builtin_va_end", powerpc_builtin_va_end }, \
- { "__builtin_va_copy", powerpc_builtin_va_copy }, \
- { "__builtin_frame_address", powerpc_builtin_frame_address }, \
- { "__builtin_return_address", powerpc_builtin_return_address },
-
-#define NODE struct node
+ { "__builtin_stdarg_start", powerpc_builtin_stdarg_start, \
+ 0, 2, 0, VOID }, \
+ { "__builtin_va_arg", powerpc_builtin_va_arg, \
+ BTNORVAL|BTNOPROTO, 2, 0, 0 }, \
+ { "__builtin_va_end", powerpc_builtin_va_end, 0, 1, 0, VOID }, \
+ { "__builtin_va_copy", powerpc_builtin_va_copy, 0, 2, 0, VOID },
+
+#ifdef LANG_CXX
+#define P1ND struct node
+#else
+#define P1ND struct p1node
+#endif
struct node;
-NODE *powerpc_builtin_stdarg_start(NODE *f, NODE *a, unsigned int);
-NODE *powerpc_builtin_va_arg(NODE *f, NODE *a, unsigned int);
-NODE *powerpc_builtin_va_end(NODE *f, NODE *a, unsigned int);
-NODE *powerpc_builtin_va_copy(NODE *f, NODE *a, unsigned int);
-NODE *powerpc_builtin_frame_address(NODE *f, NODE *a, unsigned int);
-NODE *powerpc_builtin_return_address(NODE *f, NODE *a, unsigned int);
-#undef NODE
+struct bitable;
+P1ND *powerpc_builtin_stdarg_start(const struct bitable *, P1ND *a);
+P1ND *powerpc_builtin_va_arg(const struct bitable *f, P1ND *a);
+P1ND *powerpc_builtin_va_end(const struct bitable *f, P1ND *a);
+P1ND *powerpc_builtin_va_copy(const struct bitable *f, P1ND *a);
+P1ND *powerpc_builtin_frame_address(const struct bitable *f, P1ND *a);
+P1ND *powerpc_builtin_return_address(const struct bitable *f, P1ND *a);
+#undef P1ND
#define NARGREGS 8
-/* $Id: order.c,v 1.8 2009/01/07 11:44:03 gmcgarry Exp $ */
+/* $Id: order.c,v 1.9 2016/07/10 09:49:52 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
(void)geninsn(p, INAREG);
} else if (p->n_op == REG) {
q->n_op = OREG;
- q->n_lval = p->n_lval;
+ setlval(q, getlval(p));
q->n_rval = p->n_rval;
tfree(p);
}
-.\" $Id: cc.1,v 1.43 2014/12/24 09:55:32 plunky Exp $
+.\" $Id: cc.1,v 1.44 2016/07/10 08:21:10 ragge Exp $
.\"
.\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net>
.\"
.Nd front-end to the C compiler
.Sh SYNOPSIS
.Nm
-.Op Fl cEgkMPStvX
+.Op Fl cEgkMPSstvX
.Op Fl B Ns Ar prefix
.Op Fl D Ar macro Ns Oo = Ns Ar value Oc
.Op Fl d Ns Ar flags
.Op Fl pthread
.Op Fl shared
.Op Fl static
+.Op Fl std= Ns Ar standard
.Op Fl U Ar macro
.Op Fl Wa Ns , Ns Ar options
.Op Fl Wc Ns , Ns Ar options
.Op Fl Wl Ns , Ns Ar options
.Op Fl Wp Ns , Ns Ar options
.Op Fl x Ar language
+.Op Fl z Ar keyword
.Op Ar
.Sh DESCRIPTION
The
.Fl xinline
to
.Xr ccom 1 .
-If no level is given the optimization level is increased, or
-optimizations can be disabled using
+If no level is given the optimization level is
+.Fl O1 .
+Optimizations can be disabled using
.Fl O0 .
+In situations where multiple optimization flags are given, the last flag is the
+one used.
.It Fl o Ar outfile
Save result to
.Ar outfile .
Note: cannot be combined with
.Fl o
if multiple files are given.
+.It Fl s
+Passed to
+.Xr ld 1
+to remove all symbol table and relocation information from the generated
+executable.
+This option is silently ignored if
+.Nm
+does not invoke the linker.
.It Fl shared
Create a shared object of the result.
Tells the linker not to generate an executable.
Do not use dynamic linkage.
By default, it will link using the dynamic linker options
and/or shared objects for the platform.
+.It Fl std= Ns Ar standard
+Compile to the specified
+.Ar standard .
+Accepted values for
+.Ar standard
+are
+.Ar c89 ,
+.Ar c99 ,
+.Ar gnu99 ,
+.Ar gnu9x ,
+and
+.Ar c11 .
.It Fl t
Passed to
.Xr cpp 1
.Fl x
options are passed to
.Xr ccom 1 .
+.It Fl z Ar keyword
+Passed to
+.Xr ld 1 .
+Please refer to the documentation of your linker for acceptable values of
+.Ar keyword .
.El
.Ss Predefined Macros
A few
-/* $Id: cc.c,v 1.305 2016/02/23 11:14:08 ragge Exp $ */
+/* $Id: cc.c,v 1.310 2016/08/26 13:52:57 ragge Exp $ */
/*-
* Copyright (c) 2011 Joerg Sonnenberger <joerg@NetBSD.org>.
char *name;
int flags;
#define INWALL 1
+#define INWEXTRA 2
} Wflags[] = {
{ "truncate", 0 },
{ "strict-prototypes", 0 },
- { "missing-prototypes", 0 },
+ { "missing-prototypes", INWEXTRA },
{ "implicit-int", INWALL },
{ "implicit-function-declaration", INWALL },
- { "shadow", 0 },
+ { "shadow", INWEXTRA },
{ "pointer-sign", INWALL },
- { "sign-compare", 0 },
+ { "sign-compare", INWEXTRA },
{ "unknown-pragmas", INWALL },
- { "unreachable-code", 0 },
- { "deprecated-declarations", 0 },
+ { "unreachable-code", INWEXTRA },
+ { "deprecated-declarations", INWEXTRA },
{ "attributes", 0 },
{ NULL, 0 },
};
oerror(argp);
break;
+ case 'a': /* only -ansi switch for now */
+ if (match(argp, "-ansi"))
+ cstd = SC89;
+ break;
+
case 'B': /* other search paths for binaries */
t = nxtopt("-B");
strlist_append(&crtdirs, t);
break;
case 'd': /* debug options */
+ if (match(argp, "-dumpmachine")) {
+ /* Print target and immediately exit */
+ puts(TARGSTR);
+ exit(0);
+ }
+ if (match(argp, "-dumpversion")) {
+ /* Print claimed gcc level, immediately exit */
+ puts("4.3.1");
+ exit(0);
+ }
for (t = &argp[2]; *t; t++) {
if (*t == 'M')
strlist_append(&preprocessor_flags, "-dM");
break;
}
#endif
-#if defined(mach_arm) || defined(mach_mips)
+#if defined(mach_arm) || defined(mach_mips) || defined(mach_mips64)
if (match(argp, "-mbig-endian")) {
bigendian = 1;
strlist_append(&compiler_flags, argp);
break;
}
#endif
-#if defined(mach_mips)
+#if defined(mach_mips) || defined(mach_mips64)
if (match(argp, "-mhard-float")) {
softfloat = 0;
strlist_append(&compiler_flags, argp);
} else if (match(argp, "-symbolic")) {
strlist_append(&middle_linker_flags,
"-Bsymbolic");
- } else if (strncmp(argp, "-std", 4) == 0) {
- if (strcmp(&argp[5], "gnu99") == 0 ||
+ } else if (strncmp(argp, "-std=", 5) == 0) {
+ if (strcmp(&argp[5], "c11") == 0)
+ cstd = SC11;
+ else if (strcmp(&argp[5], "gnu99") == 0 ||
strcmp(&argp[5], "gnu9x") == 0)
cstd = SGNU99;
- if (strcmp(&argp[5], "c89") == 0)
+ else if (strcmp(&argp[5], "c89") == 0)
cstd = SC89;
- if (strcmp(&argp[5], "gnu89") == 0)
+ else if (strcmp(&argp[5], "gnu89") == 0)
cstd = SGNU89;
- if (strcmp(&argp[5], "c99") == 0)
+ else if (strcmp(&argp[5], "c99") == 0)
cstd = SC99;
- } else
+ else
+ oerror(argp);
+ } else if (match(argp, "-s")) {
+ strlist_append(&middle_linker_flags, argp);
+ } else
oerror(argp);
break;
case 'O':
if (argp[2] == '\0')
- Oflag++;
+ /* gcc does -O1, clang does -O2 */
+ Oflag = 1; /* do what gcc does */
else if (argp[3] == '\0' &&
isdigit((unsigned char)argp[2]))
Oflag = argp[2] - '0';
if (Wf->flags & INWALL)
strlist_append(&compiler_flags,
cat("-W", Wf->name));
+ } else if (strcmp(argp, "-Wextra") == 0 ||
+ strcmp(argp, "-W") == 0) {
+ for (Wf = Wflags; Wf->name; Wf++)
+ if (Wf->flags & INWEXTRA)
+ strlist_append(&compiler_flags,
+ cat("-W", Wf->name));
} else if (strcmp(argp, "-WW") == 0) {
for (Wf = Wflags; Wf->name; Wf++)
strlist_append(&compiler_flags,
}
break;
+ case 'z':
+ argp = cat(argp, nxtopt(0));
+ strlist_append(&middle_linker_flags, argp);
+ break;
+
}
continue;
#if !defined(USE_YASM)
{ &vflag, 1, "-v" },
#endif
+#if defined(os_openbsd) && defined(mach_mips64)
+ { &kflag, 1, "-KPIC" },
+#else
{ &kflag, 1, "-k" },
+#endif
#ifdef os_darwin
{ &one, 1, "-arch" },
#if mach_amd64
-/* $Id: cgram.y,v 1.415 2016/04/02 09:02:56 ragge Exp $ */
+/* $Id: cgram.y,v 1.416 2016/08/09 17:30:26 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
static struct symtab *
init_declarator(P1ND *tn, P1ND *p, int assign, P1ND *a, char *as)
{
- int class = glval(tn);
+ int class = (int)glval(tn);
struct symtab *sp;
p = aryfix(p);
extern int prolab;
struct symtab *s;
P1ND *q, *typ;
- int class = glval(tp), oclass, ctval;
+ int class = (int)glval(tp), oclass, ctval;
/*
* We discard all names except for those needed for
int
con_e(P1ND *p)
{
- return icons(optloop(eve(p)));
+ return (int)icons(optloop(eve(p)));
}
void
-/* $Id: optim.c,v 1.63 2016/04/02 20:16:23 ragge Exp $ */
+/* $Id: optim.c,v 1.65 2016/07/09 15:59:43 ragge Exp $ */
/*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
p1walkf(p, putjops, 0);
p1tfree(p);
p = bcon(0);
+#ifdef notyet /* result may be logical value */
} else {
q = p->n_right;
nfree(nfree(p));
p = cast(q, INT, 0);
+#endif
}
break;
case OROR:
p1walkf(p, putjops, 0);
p1tfree(p);
p = bcon(1);
+#ifdef notyet /* result may be logical value */
} else {
q = p->n_right;
nfree(nfree(p));
p = cast(q, INT, 0);
+#endif
}
break;
}
-/* $Id: pftn.c,v 1.421 2016/03/05 15:31:24 ragge Exp $ */
+/* $Id: pftn.c,v 1.422 2016/08/09 17:30:26 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
}
al = talign(type, NULL);
- sz = tsize(type, NULL, NULL);
+ sz = (int)tsize(type, NULL, NULL);
if (w > sz) {
uerror("field too big");
switch (p->n_op) {
case ALIGN:
if (tc->align < glval(p))
- tc->align = glval(p);
+ tc->align = (int)glval(p);
break;
case ATTRIB:
#ifdef GCC_COMPAT
%{
-/* $Id: scan.l,v 1.147 2016/03/08 18:17:45 ragge Exp $ */
+/* $Id: scan.l,v 1.148 2016/08/07 08:54:56 ragge Exp $ */
/*
* Copyright (c) 2002 Anders Magnusson. All rights reserved.
static P1ND *wcharcon(void);
static void control(int);
static void pragma(void);
+static int dotfile;
int notype, parbal, inattr, parlvl, nodinit, inoso;
int kwdecode(struct symtab *s);
return xbcon(val, NULL, ctype(UNSIGNED));
}
+#ifndef MYDOTFILE
+/*
+ * Get basename and print it as '.file "basename.c"'
+ */
+static void
+printdotfile(char *file)
+{
+ char *p;
+
+ if ((p = strrchr(file, '/')) == NULL)
+ p = file;
+ else
+ p++;
+ printf(PRTPREF "\t.file \"%s\"\n", p);
+}
+#endif
+
void
control(int t)
{
if (gflag)
stabs_file(ftitle);
#endif
+ if (dotfile == 0) {
+ dotfile++;
+ printdotfile(ftitle);
+ }
}
return;
bad:
-/* $Id: trees.c,v 1.374 2016/04/02 09:47:12 ragge Exp $ */
+/* $Id: trees.c,v 1.377 2016/08/09 17:29:35 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
if (casgop(o)) {
if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
+ tr > UNSIGNED &&
DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
warner(Wtruncate, tnames[tr], tnames[tl]);
if (l->n_type == BOOL && r->n_type != BOOL) {
*/
} else {
slval(p, glval(l));
+ p->n_sp = NULL;
p->n_op = ICON;
p1nfree(l);
p1nfree(r);
logwalk(p);
if (p->n_op == ICON) {
- if (glval(p) != 0)
+ if (glval(p) != 0 || p->n_sp != NULL)
branch(label);
p1nfree(p);
} else {
-/* $Id: cpc.c,v 1.7 2016/01/10 16:17:45 ragge Exp $ */
+/* $Id: cpc.c,v 1.8 2016/08/08 16:38:29 ragge Exp $ */
/*
* Copyright (c) 2014 Anders Magnusson (ragge@ludd.luth.se).
case GE: n1->nd_val = n1->nd_val >= n2->nd_val; break;
case RS: n1->nd_val >>= n2->nd_val; break;
}
- return;
} else /* op == UNUMBER */ {
switch (op) {
case '*': n1->nd_uval *= n2->nd_uval; break;
case GE: n1->nd_uval = n1->nd_uval >= n2->nd_uval; break;
case RS: n1->nd_uval >>= n2->nd_uval; break;
}
- return;
}
- error("unexpected arithmetic");
}
-/* $Id: cpp.c,v 1.274 2016/04/12 18:49:35 ragge Exp $ */
+/* $Id: cpp.c,v 1.281 2016/08/10 17:33:23 ragge Exp $ */
/*
* Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
#define IMP(x)
#endif
+static int istty;
int Aflag, Cflag, Eflag, Mflag, dMflag, Pflag, MPflag, MMDflag;
char *Mfile, *MPfile;
char *Mxfile;
-int warnings, Mxlen;
+int warnings, Mxlen, skpows;
static usch utbuf[CPPBUF];
struct iobuf pb = { utbuf, 0, CPPBUF, 0, 1, BUTBUF };
#if LIBVMF
static void vsheap(struct iobuf *, const char *, va_list);
static int skipws(struct iobuf *ib);
static int getyp(usch *s);
+static void macsav(int ch);
+static void fstrstr(struct iobuf *ib, struct iobuf *ob);
int
main(int argc, char **argv)
if (open(argv[1], O_WRONLY|O_CREAT, 0600) < 0)
error("Can't creat %s", argv[1]);
}
+ istty = isatty(1);
if (argc && strcmp(argv[0], "-")) {
fn1 = fn2 = (usch *)argv[0];
if (pushfile(fn1, fn2, 0, NULL))
error("cannot open %s", argv[0]);
- if (Mflag == 0)
+ if (Mflag == 0) {
+ if (skpows)
+ pb.buf[pb.cptr++] = '\n';
write(1, pb.buf, pb.cptr);
+ }
#ifdef TIMING
(void)gettimeofday(&t2, NULL);
t2.tv_sec -= t1.tv_sec;
void
line(void)
{
- struct iobuf *ob;
- struct symtab *nl;
- int c, n, ln;
- usch *cp, *dp;
+ struct iobuf *ib, *ob;
+ int n, ln;
- c = skipws(0);
- if (ISID0(c)) { /* expand macro */
- dp = readid(c);
- if ((nl = lookup(dp, FIND)) == 0 || (ob = kfind(nl)) == 0)
- goto bad;
- } else {
- ob = getobuf(BNORMAL);
- do {
- putob(ob, c);
- } while (ISDIGIT(c = cinput()));
- cunput(c);
- putob(ob, 0);
- }
- cp = ob->buf;
+
+ ob = savln();
+ ob->cptr = 0;
+ ib = getobuf(BNORMAL);
+ exparg(1, ob, ib, NULL);
+
+ ib->cptr = 0;
+ while (ISWSNL(ib->buf[ib->cptr]))
+ ib->cptr++;
n = 0;
- while (ISDIGIT(*cp))
- n = n * 10 + *cp++ - '0';
- if (*cp != 0)
- goto bad;
- bufree(ob);
+ while (ISDIGIT(ib->buf[ib->cptr]))
+ n = n * 10 + ib->buf[ib->cptr++] - '0';
/* Can only be decimal number here between 1-2147483647 */
if (n < 1 || n > 2147483647)
goto bad;
+ while (ISWSNL(ib->buf[ib->cptr]))
+ ib->cptr++;
+
ln = n;
ifiles->escln = 0;
- if ((c = skipws(NULL)) != '\n') {
- if (c == 'L' || c == 'U' || c == 'u') {
- n = c, c = cinput();
- if (n == 'u' && c == '8')
- c = cinput();
- if (c == '\"')
- warning("#line only allows character literals");
- }
- if (c != '\"')
- goto bad;
- ob = faststr(c, NULL);
- if (strcmp((char *)ifiles->fname, (char *)ob->buf))
- ifiles->fname = xstrdup(ob->buf);
- bufree(ob);
+ if (ib->buf[ib->cptr] == 0)
+ goto out;
- c = skipws(0);
- }
- if (c != '\n')
+ if (getyp(ib->buf+ib->cptr) != STRING)
goto bad;
+ if (ib->buf[ib->cptr] != '\"')
+ warning("#line only allows character literals");
+
+ ob->cptr = 0;
+ fstrstr(ib, ob);
+ ob->buf[ob->cptr] = 0;
+
+ if (strcmp((char *)ifiles->fname, (char *)ob->buf))
+ ifiles->fname = xstrdup(ob->buf);
+ bufree(ob);
+
+ while (ISWSNL(ib->buf[ib->cptr]))
+ ib->cptr++;
+
+ if (ib->buf[ib->cptr] != 0)
+ goto bad;
+
+ bufree(ib);
- ifiles->lineno = ln;
+out: ifiles->lineno = ln;
prtline(1);
ifiles->lineno--;
- cunput('\n');
return;
bad: error("bad #line");
void
define(void)
{
+ extern int incmnt;
struct iobuf *ib, *ab;
struct symtab *np;
usch cc[2], *vararg, *dp;
ab = getobuf(BNORMAL);
vararg = NULL;
if ((c = cinput()) == '(') {
- type = 0;
+ type = FUNLIKE;
/* function-like macros, deal with identifiers */
c = skipws(0);
for (;;) {
/* parse replacement-list, substituting arguments */
wascon = 0;
while (c != '\n') {
- cc[0] = c, cc[1] = inc2();
+ incmnt++;
+ cc[0] = c, cc[1] = cinput();
+ incmnt--;
t = getyp(cc);
cunput(cc[1]);
(void)cinput(); /* eat # */
DELEWS();
macsav(CONC);
- if (ISID0(c = skipws(0)) && type == 0)
+ if (ISID0(c = skipws(0)) && type == FUNLIKE)
wascon = 1;
if (c == '\n')
goto bad; /* 6.10.3.3 p1 */
break;
case CMNT:
- Ccmnt(macsav);
+ Ccmnt2(macsav, cinput());
break;
case NUMBER:
pragoper(struct iobuf *ib)
{
int t;
- struct iobuf *ob = getobuf(BNORMAL);
if (skipws(ib) != '(' || ((t = skipws(ib)) != '\"' && t != 'L'))
goto err;
if (t == 'L' && (t = pragwin(ib)) != '\"')
goto err;
- strtobuf((usch *)"\n#pragma ", ob);
+ putstr((usch *)"\n#pragma ");
while ((t = pragwin(ib)) != '\"') {
if (t == BLKID) {
pragwin(ib);
continue;
if (t == '\\') {
if ((t = pragwin(ib)) != '\"' && t != '\\')
- putob(ob, '\\');
+ putch('\\');
}
- putob(ob, t);
+ putch(t);
}
- bsheap(ob, "\n# %d \"%s\"\n", ifiles->lineno, ifiles->fname);
- putstr(ob->buf);
- bufree(ob);
+ prtline(1);
if (skipws(ib) == ')')
return;
fstrnum(struct iobuf *ib, struct iobuf *ob)
{
usch *s = ib->buf+ib->cptr;
+ int c2;
if (*s == '.') {
/* not digit, dot. Next will be digit */
}
for (;;) {
putob(ob, *s++);
- if ((spechr[*s] & C_EP)) {
+ if ((c2 = (*s & 0337)) == 'E' || c2 == 'P') {
if (s[1] != '-' && s[1] != '+')
break;
putob(ob, *s++);
return;
while ((ch = cinput()) != '\n')
;
- ifiles->lineno++;
putch('\n');
+ ifiles->lineno++;
}
}
error("eof in macro");
else if (c == '/') {
int mp = macpos;
- Ccmnt(macsav);
+ if ((c = ra1_wsnl()) == '*' || c == '/')
+ Ccmnt2(macsav, c);
+ else {
+ macsav('/');
+ cunput(c);
+ }
macsav(0);
strtobuf(macbase+mp, ab);
macpos = mp;
putob(ab, c);
if ((c = cinput()) == '\n') {
chkdir();
- ifiles->lineno++, putch(c), c = ' ';
+ putch(c), ifiles->lineno++, c = ' ';
}
}
return ab;
}
+/*
+ * escape "\ inside strings.
+ */
+static void
+escstr(const usch *bp, struct iobuf *ob)
+{
+ int instr = 0;
+
+ while (*bp) {
+ if (!instr && ISWS(*bp)) {
+ while (ISWS(*bp))
+ bp++;
+ putob(ob, ' ');
+ }
+
+ if (*bp == '\'' || *bp == '"') {
+ instr ^= 1;
+ if (*bp == '"')
+ putob(ob, '\\');
+ }
+ if (instr && *bp == '\\') {
+ putob(ob, *bp);
+ if (bp[1] == '\"')
+ putob(ob, *bp), putob(ob, *bp++);
+ }
+ putob(ob, *bp);
+ bp++;
+ }
+}
+
/*
* expand a function-like macro.
* vp points to end of replacement-list
{
struct blocker *w;
struct iobuf *ob, *cb, *nb;
- int narg, instr, snuff;
- const usch *sp, *bp, *ap, *vp, *tp;
+ int narg, instr, snuff, c2;
+ const usch *sp, *bp, *ap, *vp;
DPRINT(("%d:subarg '%s'\n", lvl, nl->namep));
ob = getobuf(BNORMAL);
printf("'\n");
}
#endif
- if (sp[-2] != CONC && !snuff && sp[1] != CONC) {
+ c2 = (sp-2 < vp ? 0 : sp[-2]);
+ if (c2 != CONC && !snuff && sp[1] != CONC) {
/*
* Expand an argument; 6.10.3.1:
* "A parameter in the replacement list,
strtobuf(nb->buf, ob);
bufree(nb);
} else {
- while (*bp) {
- if (snuff && !instr && ISWS(*bp)) {
- while (ISWS(*bp))
- bp++;
- putob(ob, ' ');
- }
-
- if (snuff &&
- (*bp == '\'' || *bp == '"')) {
- instr ^= 1;
- for (tp = bp - 1; *tp == '\\'; tp--)
- instr ^= 1;
- if (*bp == '"')
- putob(ob, '\\');
- }
- if (snuff && instr && *bp == '\\')
- putob(ob, '\\');
- putob(ob, *bp);
- bp++;
- }
+ if (snuff)
+ escstr(bp, ob);
+ else
+ strtobuf(bp, ob);
}
} else if (ISID0(*sp)) {
if (lookup(sp, FIND))
}
/*
- * Do a (correct) expansion of a WARN-terminated buffer of tokens.
- * Data is read from the lex buffer, result on lex buffer, WARN-terminated.
+ * Do a (correct) expansion of a buffer of tokens.
+ * Data is read from the input buffer, result on output buffer.
* Expansion blocking is not altered here unless when tokens are
- * concatenated, in which case they are removed.
+ * concatenated, in which case the blocking is removed.
*/
struct iobuf *
exparg(int lvl, struct iobuf *ib, struct iobuf *ob, struct blocker *bl)
}
#endif
+void
+cntline(void)
+{
+ if (skpows < 10)
+ for (; skpows > 0; skpows--)
+ putob(&pb, '\n');
+ else
+ prtline(1);
+ skpows = 0;
+}
+
void
putch(int ch)
{
- putob(&pb, ch);
+ if (skpows) {
+ if (ch == '\n')
+ skpows++;
+ if (ISWSNL(ch))
+ return;
+ cntline();
+ } else if (ch == '\n' && tflag == 0) {
+ skpows = 1;
+ return;
+ }
+ if (pb.cptr == pb.bsz)
+ putob(&pb, ch);
+ else
+ pb.buf[pb.cptr++] = ch;
+ if (ch == '\n' && istty && Mflag == 0)
+ (void)write(1, pb.buf, pb.cptr), pb.cptr = 0;
+
}
void
putstr(const usch *s)
{
+ if (skpows)
+ cntline();
strtobuf(s, &pb);
}
-/* $Id: cpp.h,v 1.102 2016/04/12 18:49:35 ragge Exp $ */
+/* $Id: cpp.h,v 1.107 2016/08/10 17:33:23 ragge Exp $ */
/*
* Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
#define PBMAX 10 /* min pushbackbuffer size */
-#define CTRLOC 0xf8 /* __COUNTER__ */
-#define DEFLOC 0xf9 /* defined */
-#define PRAGLOC 0xfa /* _Pragma */
-#define LINLOC 0xfb /* __LINE__ */
-#define FILLOC 0xfc /* __FILE__ */
-#define GCCARG 0xfd /* has gcc varargs that may be replaced with 0 */
-#define VARG 0xfe /* has varargs */
-#define OBJCT 0xff
+#define FUNLIKE 0
+#define CTRLOC 1 /* __COUNTER__ */
+#define DEFLOC 2 /* defined */
+#define PRAGLOC 3 /* _Pragma */
+#define LINLOC 4 /* __LINE__ */
+#define FILLOC 5 /* __FILE__ */
+#define GCCARG 6 /* has gcc varargs that may be replaced with 0 */
+#define VARG 7 /* has varargs */
+#define OBJCT 8
+
#define WARN 1 /* SOH, not legal char */
#define CONC 2 /* STX, not legal char */
#define SNUFF 3 /* ETX, not legal char */
#define C_WSNL 0004 /* ' ','\t','\r','\n' */
#define C_ID 0010 /* [_a-zA-Z0-9] */
#define C_ID0 0020 /* [_a-zA-Z] */
-#define C_EP 0040 /* [epEP] */
+#define C_Q 0040 /* [\r\\\?] */
#define C_DIGIT 0100 /* [0-9] */
#define C_HEX 0200 /* [0-9a-fA-F] */
#define ISID(x) (spechr[x] & C_ID)
#define ISID0(x) (spechr[x] & C_ID0)
#define ISDIGIT(x) (spechr[x] & C_DIGIT)
+#define ISCQ(x) (spechr[x] & C_Q)
/* buffer definition */
#define BNORMAL 0 /* standard buffer */
const usch *value;
const usch *file;
int line;
- unsigned char type; /* macro type */
+ unsigned char type:4, /* macro type */
+ wraps:1; /* macro wraps in buffer */
unsigned char narg; /* # of args (if feasible) */
};
void error(const char *fmt, ...);
int cinput(void);
int inc2(void);
-int Ccmnt(void (*d)(int));
+void Ccmnt2(void (*d)(int), int);
usch *bufid(int ch, struct iobuf *);
usch *readid(int ch);
struct iobuf *faststr(int bc, struct iobuf *);
void *xrealloc(void *p, int sz);
void *xmalloc(int sz);
void fastscan(void);
+void cntline(void);
+struct iobuf *savln(void);
+++ /dev/null
-%{
-/* $Id: scanner.l,v 1.50 2011/06/03 15:42:45 plunky Exp $ */
-
-/*
- * Copyright (c) 2004 Anders Magnusson. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-
-#include "compat.h"
-#include "cpp.h"
-#include "y.tab.h"
-%}
-
-%{
-static void cvtdig(int rad);
-static int charcon(usch *);
-static void elsestmt(void);
-static void ifdefstmt(void);
-static void ifndefstmt(void);
-static void endifstmt(void);
-static void ifstmt(void);
-static void cpperror(void);
-static void pragmastmt(void);
-static void undefstmt(void);
-static void cpperror(void);
-static void elifstmt(void);
-static void storepb(void);
-static void badop(const char *);
-void include(void);
-void define(void);
-
-extern int yyget_lineno (void);
-extern void yyset_lineno (int);
-
-static int inch(void);
-
-static int scale, gotdef, contr;
-int inif;
-
-#ifdef FLEX_SCANNER /* should be set by autoconf instead */
-static int
-yyinput(char *b, int m)
-{
- int c, i;
-
- for (i = 0; i < m; i++) {
- if ((c = inch()) < 0)
- break;
- *b++ = c;
- if (c == '\n') {
- i++;
- break;
- }
- }
- return i;
-}
-#undef YY_INPUT
-#undef YY_BUF_SIZE
-#define YY_BUF_SIZE (8*65536)
-#define YY_INPUT(b,r,m) (r = yyinput(b, m))
-#ifdef HAVE_CPP_VARARG_MACRO_GCC
-#define fprintf(x, ...) error(__VA_ARGS__)
-#endif
-#define ECHO putstr((usch *)yytext)
-#undef fileno
-#define fileno(x) 0
-
-#if YY_FLEX_SUBMINOR_VERSION >= 31
-/* Hack to avoid unnecessary warnings */
-FILE *yyget_in (void);
-FILE *yyget_out (void);
-int yyget_leng (void);
-char *yyget_text (void);
-void yyset_in (FILE * in_str );
-void yyset_out (FILE * out_str );
-int yyget_debug (void);
-void yyset_debug (int bdebug );
-int yylex_destroy (void);
-#endif
-#else /* Assume lex here */
-#undef input
-#undef unput
-#define input() inch()
-#define unput(ch) unch(ch)
-#endif
-#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
-/* protection against recursion in #include */
-#define MAX_INCLEVEL 100
-static int inclevel;
-%}
-
-D [0-9]
-L [a-zA-Z_]
-H [a-fA-F0-9]
-E [Ee][+-]?{D}+
-FS (f|F|l|L)
-IS (u|U|l|L)*
-WS [\t ]
-
-%s IFR CONTR DEF COMMENT
-
-%%
-
-"\n" { int os = YYSTATE;
- if (os != IFR)
- BEGIN 0;
- ifiles->lineno++;
- if (flslvl == 0) {
- if (ifiles->lineno == 1)
- prtline();
- else
- putch('\n');
- }
- if ((os != 0 || slow) && !contr)
- return '\n';
- contr = 0;
- }
-
-"\r" { ; /* Ignore CR's */ }
-
-<IFR>"++" { badop("++"); }
-<IFR>"--" { badop("--"); }
-<IFR>"==" { return EQ; }
-<IFR>"!=" { return NE; }
-<IFR>"<=" { return LE; }
-<IFR>"<<" { return LS; }
-<IFR>">>" { return RS; }
-<IFR>">=" { return GE; }
-<IFR>"||" { return OROR; }
-<IFR>"&&" { return ANDAND; }
-<IFR>"defined" { int p, c;
- gotdef = 1;
- if ((p = c = yylex()) == '(')
- c = yylex();
- if (c != IDENT || (p != IDENT && p != '('))
- error("syntax error");
- if (p == '(' && yylex() != ')')
- error("syntax error");
- return NUMBER;
- }
-
-<IFR>{WS}+ { ; }
-<IFR>{L}({L}|{D})* {
- yylval.node.op = NUMBER;
- if (gotdef) {
- yylval.node.nd_val
- = lookup((usch *)yytext, FIND) != 0;
- gotdef = 0;
- return IDENT;
- }
- yylval.node.nd_val = 0;
- return NUMBER;
- }
-
-[0-9][0-9]* {
- if (slow && !YYSTATE)
- return IDENT;
- scale = yytext[0] == '0' ? 8 : 10;
- goto num;
- }
-
-0[xX]{H}+{IS}? { scale = 16;
- num: if (YYSTATE == IFR)
- cvtdig(scale);
- PRTOUT(NUMBER);
- }
-0{D}+{IS}? { scale = 8; goto num; }
-{D}+{IS}? { scale = 10; goto num; }
-'(\\.|[^\\'])+' {
- if (YYSTATE || slow) {
- yylval.node.op = NUMBER;
- yylval.node.nd_val = charcon((usch *)yytext);
- return (NUMBER);
- }
- if (tflag)
- yyless(1);
- if (!flslvl)
- putstr((usch *)yytext);
- }
-
-<IFR>. { return yytext[0]; }
-
-{D}+{E}{FS}? { PRTOUT(FPOINT); }
-{D}*"."{D}+({E})?{FS}? { PRTOUT(FPOINT); }
-{D}+"."{D}*({E})?{FS}? { PRTOUT(FPOINT); }
-
-^{WS}*#{WS}* { extern int inmac;
-
- if (inmac)
- error("preprocessor directive found "
- "while expanding macro");
- contr = 1;
- BEGIN CONTR;
- }
-{WS}+ { PRTOUT(WSPACE); }
-
-<CONTR>"ifndef" { contr = 0; ifndefstmt(); }
-<CONTR>"ifdef" { contr = 0; ifdefstmt(); }
-<CONTR>"if" { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; }
-<CONTR>"include" { contr = 0; BEGIN 0; include(); prtline(); }
-<CONTR>"else" { contr = 0; elsestmt(); }
-<CONTR>"endif" { contr = 0; endifstmt(); }
-<CONTR>"error" { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; }
-<CONTR>"define" { contr = 0; BEGIN DEF; define(); BEGIN 0; }
-<CONTR>"undef" { contr = 0; if (slow) return IDENT; undefstmt(); }
-<CONTR>"line" { contr = 0; storepb(); BEGIN 0; line(); }
-<CONTR>"pragma" { contr = 0; pragmastmt(); BEGIN 0; }
-<CONTR>"elif" { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; }
-
-
-
-"//".*$ { /* if (tflag) yyless(..) */
- if (Cflag && !flslvl && !slow)
- putstr((usch *)yytext);
- else if (!flslvl)
- putch(' ');
- }
-"/*" { int c, wrn;
- int prtcm = Cflag && !flslvl && !slow;
- extern int readmac;
-
- if (Cflag && !flslvl && readmac)
- return CMNT;
-
- if (prtcm)
- putstr((usch *)yytext);
- wrn = 0;
- more: while ((c = input()) && c != '*') {
- if (c == '\n')
- putch(c), ifiles->lineno++;
- else if (c == 1) /* WARN */
- wrn = 1;
- else if (prtcm)
- putch(c);
- }
- if (c == 0)
- return 0;
- if (prtcm)
- putch(c);
- if ((c = input()) && c != '/') {
- unput(c);
- goto more;
- }
- if (prtcm)
- putch(c);
- if (c == 0)
- return 0;
- if (!tflag && !Cflag && !flslvl)
- unput(' ');
- if (wrn)
- unput(1);
- }
-
-<DEF>"##" { return CONCAT; }
-<DEF>"#" { return MKSTR; }
-<DEF>"..." { return ELLIPS; }
-<DEF>"__VA_ARGS__" { return VA_ARGS; }
-
-L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
-[a-zA-Z_0-9]+ { /* {L}({L}|{D})* */
- struct symtab *nl;
- if (slow)
- return IDENT;
- if (YYSTATE == CONTR) {
- if (flslvl == 0) {
- /*error("undefined control");*/
- while (input() != '\n')
- ;
- unput('\n');
- BEGIN 0;
- goto xx;
- } else {
- BEGIN 0; /* do nothing */
- }
- }
- if (flslvl) {
- ; /* do nothing */
- } else if (isdigit((int)yytext[0]) == 0 &&
- (nl = lookup((usch *)yytext, FIND)) != 0) {
- usch *op = stringbuf;
- putstr(gotident(nl));
- stringbuf = op;
- } else
- putstr((usch *)yytext);
- xx: ;
- }
-
-. {
- if (contr) {
- while (input() != '\n')
- ;
- unput('\n');
- BEGIN 0;
- contr = 0;
- goto yy;
- }
- if (YYSTATE || slow)
- return yytext[0];
- if (yytext[0] == 6) { /* PRAGS */
- usch *obp = stringbuf;
- extern usch *prtprag(usch *);
- *stringbuf++ = yytext[0];
- do {
- *stringbuf = input();
- } while (*stringbuf++ != 14);
- prtprag(obp);
- stringbuf = obp;
- } else {
- PRTOUT(yytext[0]);
- }
- yy:;
- }
-
-%%
-
-usch *yyp, yybuf[CPPBUF];
-
-int yylex(void);
-int yywrap(void);
-
-static int
-inpch(void)
-{
- int len;
-
- if (ifiles->curptr < ifiles->maxread)
- return *ifiles->curptr++;
-
- if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
- error("read error on file %s", ifiles->orgfn);
- if (len == 0)
- return -1;
- ifiles->curptr = ifiles->buffer;
- ifiles->maxread = ifiles->buffer + len;
- return inpch();
-}
-
-#define unch(c) *--ifiles->curptr = c
-
-static int
-inch(void)
-{
- int c;
-
-again: switch (c = inpch()) {
- case '\\': /* continued lines */
-msdos: if ((c = inpch()) == '\n') {
- ifiles->lineno++;
- putch('\n');
- goto again;
- } else if (c == '\r')
- goto msdos;
- unch(c);
- return '\\';
- case '?': /* trigraphs */
- if ((c = inpch()) != '?') {
- unch(c);
- return '?';
- }
- switch (c = inpch()) {
- case '=': c = '#'; break;
- case '(': c = '['; break;
- case ')': c = ']'; break;
- case '<': c = '{'; break;
- case '>': c = '}'; break;
- case '/': c = '\\'; break;
- case '\'': c = '^'; break;
- case '!': c = '|'; break;
- case '-': c = '~'; break;
- default:
- unch(c);
- unch('?');
- return '?';
- }
- unch(c);
- goto again;
- default:
- return c;
- }
-}
-
-/*
- * Let the command-line args be faked defines at beginning of file.
- */
-static void
-prinit(struct initar *it, struct includ *ic)
-{
- char *a, *pre, *post;
-
- if (it->next)
- prinit(it->next, ic);
- pre = post = NULL; /* XXX gcc */
- switch (it->type) {
- case 'D':
- pre = "#define ";
- if ((a = strchr(it->str, '=')) != NULL) {
- *a = ' ';
- post = "\n";
- } else
- post = " 1\n";
- break;
- case 'U':
- pre = "#undef ";
- post = "\n";
- break;
- case 'i':
- pre = "#include \"";
- post = "\"\n";
- break;
- default:
- error("prinit");
- }
- strlcat((char *)ic->buffer, pre, CPPBUF+1);
- strlcat((char *)ic->buffer, it->str, CPPBUF+1);
- if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
- error("line exceeds buffer size");
-
- ic->lineno--;
- while (*ic->maxread)
- ic->maxread++;
-}
-
-/*
- * A new file included.
- * If ifiles == NULL, this is the first file and already opened (stdin).
- * Return 0 on success, -1 if file to be included is not found.
- */
-int
-pushfile(usch *file)
-{
- extern struct initar *initar;
- struct includ ibuf;
- struct includ *ic;
- int c, otrulvl;
-
- ic = &ibuf;
- ic->next = ifiles;
-
- slow = 0;
- if (file != NULL) {
- if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
- return -1;
- ic->orgfn = ic->fname = file;
- if (++inclevel > MAX_INCLEVEL)
- error("Limit for nested includes exceeded");
- } else {
- ic->infil = 0;
- ic->orgfn = ic->fname = (usch *)"<stdin>";
- }
- ic->buffer = ic->bbuf+NAMEMAX;
- ic->curptr = ic->buffer;
- ifiles = ic;
- ic->lineno = 1;
- ic->maxread = ic->curptr;
- prtline();
- if (initar) {
- *ic->maxread = 0;
- prinit(initar, ic);
- if (dMflag)
- write(ofd, ic->buffer, strlen((char *)ic->buffer));
- initar = NULL;
- }
-
- otrulvl = trulvl;
-
- if ((c = yylex()) != 0)
- error("yylex returned %d", c);
-
- if (otrulvl != trulvl || flslvl)
- error("unterminated conditional");
-
- ifiles = ic->next;
- close(ic->infil);
- inclevel--;
- return 0;
-}
-
-/*
- * Print current position to output file.
- */
-void
-prtline()
-{
- usch *s, *os = stringbuf;
-
- if (Mflag) {
- if (dMflag)
- return; /* no output */
- if (ifiles->lineno == 1) {
- s = sheap("%s: %s\n", Mfile, ifiles->fname);
- write(ofd, s, strlen((char *)s));
- }
- } else if (!Pflag)
- putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
- stringbuf = os;
-}
-
-void
-cunput(int c)
-{
-#ifdef PCC_DEBUG
- extern int dflag;
- if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
-#endif
- unput(c);
-}
-
-int yywrap(void) { return 1; }
-
-static int
-dig2num(int c)
-{
- if (c >= 'a')
- c = c - 'a' + 10;
- else if (c >= 'A')
- c = c - 'A' + 10;
- else
- c = c - '0';
- return c;
-}
-
-/*
- * Convert string numbers to unsigned long long and check overflow.
- */
-static void
-cvtdig(int rad)
-{
- unsigned long long rv = 0;
- unsigned long long rv2 = 0;
- char *y = yytext;
- int c;
-
- c = *y++;
- if (rad == 16)
- y++;
- while (isxdigit(c)) {
- rv = rv * rad + dig2num(c);
- /* check overflow */
- if (rv / rad < rv2)
- error("Constant \"%s\" is out of range", yytext);
- rv2 = rv;
- c = *y++;
- }
- y--;
- while (*y == 'l' || *y == 'L')
- y++;
- yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
- yylval.node.nd_uval = rv;
- if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
- yylval.node.op = UNUMBER;
- if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
- /* too large for signed */
- error("Constant \"%s\" is out of range", yytext);
-}
-
-static int
-charcon(usch *p)
-{
- int val, c;
-
- p++; /* skip first ' */
- val = 0;
- if (*p++ == '\\') {
- switch (*p++) {
- case 'a': val = '\a'; break;
- case 'b': val = '\b'; break;
- case 'f': val = '\f'; break;
- case 'n': val = '\n'; break;
- case 'r': val = '\r'; break;
- case 't': val = '\t'; break;
- case 'v': val = '\v'; break;
- case '\"': val = '\"'; break;
- case '\'': val = '\''; break;
- case '\\': val = '\\'; break;
- case 'x':
- while (isxdigit(c = *p)) {
- val = val * 16 + dig2num(c);
- p++;
- }
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
- p--;
- while (isdigit(c = *p)) {
- val = val * 8 + (c - '0');
- p++;
- }
- break;
- default: val = p[-1];
- }
-
- } else
- val = p[-1];
- return val;
-}
-
-static void
-chknl(int ignore)
-{
- int t;
-
- slow = 1;
- while ((t = yylex()) == WSPACE)
- ;
- if (t != '\n') {
- if (ignore) {
- warning("newline expected, got \"%s\"", yytext);
- /* ignore rest of line */
- while ((t = yylex()) && t != '\n')
- ;
- }
- else
- error("newline expected, got \"%s\"", yytext);
- }
- slow = 0;
-}
-
-static void
-elsestmt(void)
-{
- if (flslvl) {
- if (elflvl > trulvl)
- ;
- else if (--flslvl!=0) {
- flslvl++;
- } else {
- trulvl++;
- prtline();
- }
- } else if (trulvl) {
- flslvl++;
- trulvl--;
- } else
- error("If-less else");
- if (elslvl==trulvl+flslvl)
- error("Too many else");
- elslvl=trulvl+flslvl;
- chknl(1);
-}
-
-static void
-ifdefstmt(void)
-{
- int t;
-
- if (flslvl) {
- /* just ignore the rest of the line */
- while (input() != '\n')
- ;
- unput('\n');
- yylex();
- flslvl++;
- return;
- }
- slow = 1;
- do
- t = yylex();
- while (t == WSPACE);
- if (t != IDENT)
- error("bad ifdef");
- slow = 0;
- if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
- trulvl++;
- else
- flslvl++;
- chknl(0);
-}
-
-static void
-ifndefstmt(void)
-{
- int t;
-
- slow = 1;
- do
- t = yylex();
- while (t == WSPACE);
- if (t != IDENT)
- error("bad ifndef");
- slow = 0;
- if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
- trulvl++;
- else
- flslvl++;
- chknl(0);
-}
-
-static void
-endifstmt(void)
-{
- if (flslvl) {
- flslvl--;
- if (flslvl == 0)
- prtline();
- } else if (trulvl)
- trulvl--;
- else
- error("If-less endif");
- if (flslvl == 0)
- elflvl = 0;
- elslvl = 0;
- chknl(1);
-}
-
-/*
- * Note! Ugly!
- * Walk over the string s and search for defined, and replace it with
- * spaces and a 1 or 0.
- */
-static void
-fixdefined(usch *s)
-{
- usch *bc, oc;
-
- for (; *s; s++) {
- if (*s != 'd')
- continue;
- if (memcmp(s, "defined", 7))
- continue;
- /* Ok, got defined, can scratch it now */
- memset(s, ' ', 7);
- s += 7;
-#define WSARG(x) (x == ' ' || x == '\t')
- if (*s != '(' && !WSARG(*s))
- continue;
- while (WSARG(*s))
- s++;
- if (*s == '(')
- s++;
- while (WSARG(*s))
- s++;
-#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
-#define NUMARG(x) (x >= '0' && x <= '9')
- if (!IDARG(*s))
- error("bad defined arg");
- bc = s;
- while (IDARG(*s) || NUMARG(*s))
- s++;
- oc = *s;
- *s = 0;
- *bc = (lookup(bc, FIND) != 0) + '0';
- memset(bc+1, ' ', s-bc-1);
- *s = oc;
- }
-}
-
-/*
- * get the full line of identifiers after an #if, pushback a WARN and
- * the line and prepare for expmac() to expand.
- * This is done before switching state. When expmac is finished,
- * pushback the expanded line, change state and call yyparse.
- */
-static void
-storepb(void)
-{
- usch *opb = stringbuf;
- int c;
-
- while ((c = input()) != '\n') {
- if (c == '/') {
- if ((c = input()) == '*') {
- /* ignore comments here whatsoever */
- usch *g = stringbuf;
- getcmnt();
- stringbuf = g;
- continue;
- } else if (c == '/') {
- while ((c = input()) && c != '\n')
- ;
- break;
- }
- unput(c);
- c = '/';
- }
- savch(c);
- }
- cunput('\n');
- savch(0);
- fixdefined(opb); /* XXX can fail if #line? */
- cunput(1); /* WARN XXX */
- unpstr(opb);
- stringbuf = opb;
- slow = 1;
- expmac(NULL);
- slow = 0;
- /* line now expanded */
- while (stringbuf > opb)
- cunput(*--stringbuf);
-}
-
-static void
-ifstmt(void)
-{
- if (flslvl == 0) {
- slow = 1;
- if (yyparse())
- ++trulvl;
- else
- ++flslvl;
- slow = 0;
- } else
- ++flslvl;
-}
-
-static void
-elifstmt(void)
-{
- if (flslvl == 0)
- elflvl = trulvl;
- if (flslvl) {
- if (elflvl > trulvl)
- ;
- else if (--flslvl!=0)
- ++flslvl;
- else {
- slow = 1;
- if (yyparse()) {
- ++trulvl;
- prtline();
- } else
- ++flslvl;
- slow = 0;
- }
- } else if (trulvl) {
- ++flslvl;
- --trulvl;
- } else
- error("If-less elif");
-}
-
-static usch *
-svinp(void)
-{
- int c;
- usch *cp = stringbuf;
-
- while ((c = input()) && c != '\n')
- savch(c);
- savch('\n');
- savch(0);
- BEGIN 0;
- return cp;
-}
-
-static void
-cpperror(void)
-{
- usch *cp;
- int c;
-
- if (flslvl)
- return;
- c = yylex();
- if (c != WSPACE && c != '\n')
- error("bad error");
- cp = svinp();
- if (flslvl)
- stringbuf = cp;
- else
- error("%s", cp);
-}
-
-static void
-undefstmt(void)
-{
- struct symtab *np;
-
- slow = 1;
- if (yylex() != WSPACE || yylex() != IDENT)
- error("bad undef");
- if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
- np->value = 0;
- slow = 0;
- chknl(0);
-}
-
-static void
-pragmastmt(void)
-{
- int c;
-
- slow = 1;
- if (yylex() != WSPACE)
- error("bad pragma");
- if (!flslvl)
- putstr((usch *)"#pragma ");
- do {
- c = input();
- if (!flslvl)
- putch(c); /* Do arg expansion instead? */
- } while (c && c != '\n');
- ifiles->lineno++;
- prtline();
- slow = 0;
-}
-
-static void
-badop(const char *op)
-{
- error("invalid operator in preprocessor expression: %s", op);
-}
-
-int
-cinput()
-{
- return input();
-}
2 2 2 2 2;
-
-
-
-
-
-
-
-
-
-
-
-
+# 19 "<stdin>"
(0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0,
--> 24 24
-
+
--> 28 28
-
+
--> 36 36
-
+
--> 40 40
-
+
--> 57 57
multi-line macro embedded
--> 59 59
-
+
--> 64 64
macro with a leading comment
--> 66 66
-
+
--> 70 70
--> 87 87
--> 89 89
-
+
#pragma with a preceding comment
# 90 "<stdin>"
--> 28 28
- /*/ comment with escaped newlines /*
- in the markers
+/*/ comment with escaped newlines /*
+in the markers
*/
--> 40 40
- // C++ comment with leading whitespace and escaped newlines
+// C++ comment with leading whitespace and escaped newlines
--> 64 64
BAR
--> 66 66
-
+
--> 70 70
# 1 "<stdin>"
-
-
-
-
-
-
-
-
-
-
-
-
-
+# 15 "<stdin>"
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))
^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
-
-
-
-
-
-
# 1 "<stdin>"
int j[] = { 123, 45, 67, 89,
- 10, 11, 12, };
+10, 11, 12, };
-
-(hej.s_s.s_pos)
+(hej.s_s.s_pos)
-/* $Id: token.c,v 1.172 2016/04/12 18:49:35 ragge Exp $ */
+/* $Id: token.c,v 1.182 2016/08/10 17:33:23 ragge Exp $ */
/*
* Copyright (c) 2004,2009 Anders Magnusson. All rights reserved.
static void pragmastmt(void);
static void elifstmt(void);
-static int inpch(void);
-static int chktg(void);
-static int chkucn(void);
static void unch(int c);
-#define PUTCH(ch) if (!flslvl) putch(ch)
+#define UNCH(ib, ch) ib->buf[--ib->cptr] = ch
/* protection against recursion in #include */
#define MAX_INCLEVEL 100
int inclevel;
+int incmnt, instr;
+extern int skpows;
struct includ *ifiles;
+static void ucn(int n);
+static void fastcmnt2(int);
+static int chktg2(int ch);
+
/* some common special combos for init */
#define C_NL (C_SPEC|C_WSNL)
#define C_DX (C_SPEC|C_ID|C_DIGIT|C_HEX)
#define C_I (C_SPEC|C_ID|C_ID0)
-#define C_IP (C_SPEC|C_ID|C_ID0|C_EP)
#define C_IX (C_SPEC|C_ID|C_ID0|C_HEX)
-#define C_IXE (C_SPEC|C_ID|C_ID0|C_HEX|C_EP)
usch spechr[256] = {
- 0, 0, 0, 0, C_SPEC, C_SPEC, 0, 0,
- 0, C_WSNL, C_NL, 0, 0, C_WSNL, 0, 0,
+ C_SPEC|C_Q, 0, 0, 0, C_SPEC, C_SPEC, 0, 0,
+ 0, C_WSNL, C_NL, 0, 0, C_WSNL|C_Q, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
C_WSNL, C_2, C_SPEC, 0, 0, 0, C_2, C_SPEC,
- 0, 0, 0, C_2, 0, C_2, 0, C_SPEC,
+ 0, 0, 0, C_2, 0, C_2, 0, C_SPEC|C_Q,
C_DX, C_DX, C_DX, C_DX, C_DX, C_DX, C_DX, C_DX,
- C_DX, C_DX, 0, 0, C_2, C_2, C_2, C_SPEC,
+ C_DX, C_DX, 0, 0, C_2, C_2, C_2, C_SPEC|C_Q,
- 0, C_IX, C_IX, C_IX, C_IX, C_IXE, C_IX, C_I,
+ 0, C_IX, C_IX, C_IX, C_IX, C_IX, C_IX, C_I,
+ C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
- C_IP, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
- C_I, C_I, C_I, 0, C_SPEC, 0, 0, C_I,
+ C_I, C_I, C_I, 0, C_SPEC|C_Q, 0, 0, C_I,
- 0, C_IX, C_IX, C_IX, C_IX, C_IXE, C_IX, C_I,
+ 0, C_IX, C_IX, C_IX, C_IX, C_IX, C_IX, C_I,
+ C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
- C_IP, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
C_I, C_I, C_I, 0, C_2, 0, 0, 0,
/* utf-8 */
/*
* fill up the input buffer
+ * n tells how nany chars at least. 0 == standard.
+ * 0 if EOF, != 0 if something could fill up buf.
*/
static int
-inpbuf(void)
+inpbuf(int n)
{
- int len;
+ struct iobuf *ib = ifiles->ib;
+ int len, sz = 0;
+
+ if (n > 0) {
+ if (ib->bsz > ib->cptr + n)
+ return 1; /* enough in buffer */
+ sz = ib->bsz - ib->cptr;
+ memcpy(ib->buf+PBMAX - sz, ib->buf + ib->cptr, sz);
+ }
if (ifiles->infil == -1)
return 0;
- len = read(ifiles->infil, ifiles->buffer, CPPBUF-PBMAX);
+ len = read(ifiles->infil, ib->buf+PBMAX, CPPBUF-PBMAX);
if (len == -1)
error("read error on file %s", ifiles->orgfn);
if (len > 0) {
- ifiles->ib->cptr = PBMAX;
- ifiles->ib->bsz = PBMAX + len;
+ ib->cptr = PBMAX - sz;
+ ib->bsz = PBMAX + len;
}
- return len;
+ return len + sz;
}
/*
- * Fillup input buffer to contain at least minsz characters.
+ * Return a quick-cooked character.
+ * If buffer empty; return 0.
*/
static int
-refill(int minsz)
+qcchar(void)
{
- usch *dp;
- int i, sz;
-
- if (ifiles->curptr+minsz < ifiles->maxread)
- return 0; /* already enough in input buffer */
-
- sz = ifiles->ib->bsz - ifiles->ib->cptr;
- dp = ifiles->ib->buf+PBMAX - sz;
- for (i = 0; i < sz; i++)
- dp[i] = ifiles->ib->buf[ifiles->ib->cptr+i];
- i = inpbuf();
- ifiles->ib->cptr = dp - ifiles->ib->buf;
- if (i == 0) {
- ifiles->ib->bsz = PBMAX;
- ifiles->ib->buf[PBMAX] = 0;
- }
- return 0;
-}
-#define REFILL(x) if (ifiles->curptr+x >= ifiles->maxread) refill(x)
+ struct iobuf *ib = ifiles->ib;
+ int ch;
-/*
- * return a raw character from the input stream
- */
-static inline int
-inpch(void)
-{
+newone: do {
+ if (ib->cptr < ib->bsz) {
+ if (!ISCQ(ch = ib->buf[ib->cptr++]))
+ return ch;
+ break;
+ }
+ } while ((ch = inpbuf(0)) > 0);
- do {
- if (ifiles->ib->cptr < ifiles->ib->bsz)
- return ifiles->ib->buf[ifiles->ib->cptr++];
- } while (inpbuf() > 0);
+ switch (ch) {
+ case 0:
+ return 0; /* end of file */
+
+ case '\r':
+ goto newone;
- return -1;
+ case '\\':
+ if (ib->cptr == ib->bsz)
+ inpbuf(0);
+ switch (ch = ib->buf[ib->cptr]) {
+ case 'u':
+ case 'U':
+ if (incmnt)
+ return '\\';
+ ib->cptr++;
+ ucn(ch == 'u' ? 4 : 8);
+ break;
+ case '\r':
+ ib->cptr++;
+ if (ib->cptr == ib->bsz)
+ inpbuf(0);
+ /* FALLTHROUGH */
+ case '\n':
+ ib->cptr++;
+ ifiles->escln++;
+ break;
+ default:
+ return '\\';
+ }
+ goto newone;
+
+ case '?':
+ inpbuf(2);
+ if (ib->buf[ib->cptr] == '?') {
+ if ((ch = chktg2(ib->buf[ib->cptr+1])) == 0)
+ return '?';
+ ib->buf[++ib->cptr] = ch;
+ goto newone;
+ }
+ return '?';
+
+ case '/':
+ if (Cflag || incmnt || instr)
+ return '/';
+ incmnt++;
+ ch = qcchar();
+ incmnt--;
+ if (ch == '/' || ch == '*') {
+ int n = ifiles->lineno;
+ fastcmnt2(ch);
+ if (n == ifiles->lineno)
+ return ' ';
+ } else {
+ ib->buf[--ib->cptr] = ch;
+ return '/';
+ }
+ goto newone;
+ }
+ error("ch error");
+ return 0; /* XXX */
}
/*
}
/*
- * Check for (and convert) trigraphs.
+ * Return trigraph mapping char or 0.
*/
static int
-chktg(void)
+chktg2(int ch)
{
- int ch;
-
- if ((ch = inpch()) != '?') {
- unch(ch);
- return 0;
- }
-
- switch (ch = inpch()) {
+ switch (ch) {
case '=': return '#';
case '(': return '[';
case ')': return ']';
case '!': return '|';
case '-': return '~';
}
-
- unch(ch);
- unch('?');
return 0;
}
-/*
- * 5.1.1.2 Translation phase 1.
- */
-static int
-inc1(void)
-{
- int ch, c2;
-
- do {
- ch = inpch();
- } while (ch == '\r' || (ch == '\\' && chkucn()));
- if (ch == '?' && (c2 = chktg()))
- ch = c2;
- return ch;
-}
-
-
-/*
- * 5.1.1.2 Translation phase 2.
- */
-int
-inc2(void)
-{
- int ch, c2;
-
- if ((ch = inc1()) != '\\')
- return ch;
- if ((c2 = inc1()) == '\n') {
- ifiles->escln++;
- ch = inc2();
- } else
- unch(c2);
- return ch;
-}
-
-static int incmnt;
/*
* deal with comments in the fast scanner.
- * ps prints out the initial '/' if failing to batch comment.
*/
-static int
-fastcmnt(int ps)
+static void
+fastcmnt2(int ch)
{
- int ch, rv = 1;
incmnt = 1;
- if ((ch = inc2()) == '/') { /* C++ comment */
- while ((ch = inc2()) != '\n')
+ if (ch == '/') { /* C++ comment */
+ while ((ch = qcchar()) != '\n')
;
unch(ch);
} else if (ch == '*') {
for (;;) {
- if ((ch = inc2()) < 0)
+ if ((ch = qcchar()) == 0)
break;
if (ch == '*') {
- if ((ch = inc2()) == '/') {
+ if ((ch = qcchar()) == '/') {
break;
} else
unch(ch);
} else if (ch == '\n') {
- ifiles->lineno++;
putch('\n');
+ ifiles->lineno++;
}
}
- } else {
- if (ps) PUTCH('/'); /* XXX ? */
- unch(ch);
- rv = 0;
- }
- if (ch < 0)
+ } else
+ error("fastcmnt2");
+ if (ch == 0)
error("file ends in comment");
incmnt = 0;
- return rv;
-}
-
-/*
- * return next char, partly phase 3.
- */
-static int
-inch(void)
-{
- int ch, n;
-
- ch = inc2();
- n = ifiles->lineno;
- if (ch == '/' && Cflag == 0 && fastcmnt(0)) {
- /* Comments 5.1.1.2 p3 */
- /* no space if traditional or multiline */
- ch = (tflag || n != ifiles->lineno) ? inch() : ' ';
- }
- return ch;
}
/*
* check for universal-character-name on input, and
* unput to the pushback buffer encoded as UTF-8.
*/
-static int
-chkucn(void)
+static void
+ucn(int n)
{
unsigned long cp, m;
- int ch, n;
+ int ch;
- if (incmnt)
- return 0;
- if ((ch = inpch()) == -1)
- return 0;
- if (ch == 'u')
- n = 4;
- else if (ch == 'U')
- n = 8;
- else {
- unch(ch);
- return 0;
+ if (incmnt) {
+ struct iobuf *ib = ifiles->ib;
+ ib->cptr--; /* [uU] */
+ ib->buf[--ib->cptr] = '\\';
+ return;
}
cp = 0;
while (n-- > 0) {
- if ((ch = inpch()) == -1 || (spechr[ch] & C_HEX) == 0) {
+ if ((ch = qcchar()) == 0 || (spechr[ch] & C_HEX) == 0) {
warning("invalid universal character name");
// XXX should actually unput the chars and return 0
unch(ch); // XXX eof
m >>= (n++ ? 1 : 2);
}
unch(((m << 1) ^ 0xfe) | cp);
- return 1;
}
/*
* deal with comments when -C is active.
* Save comments in expanded macros???
*/
-int
-Ccmnt(void (*d)(int))
+void
+Ccmnt2(void (*d)(int), int ch)
{
- int ch;
- if ((ch = inch()) == '/') { /* C++ comment */
+ if (ch == '/') { /* C++ comment */
d(ch);
do {
d(ch);
- } while ((ch = inch()) != '\n');
+ } while ((ch = qcchar()) && ch != '\n');
unch(ch);
- return 1;
} else if (ch == '*') {
d('/');
d('*');
for (;;) {
- ch = inch();
+ ch = qcchar();
d(ch);
if (ch == '*') {
- if ((ch = inch()) == '/') {
+ if ((ch = qcchar()) == '/') {
d(ch);
- return 1;
+ break;
} else
unch(ch);
} else if (ch == '\n') {
}
}
}
- d('/');
- unch(ch);
- return 0;
}
/*
{
int ch;
- while ((ch = inch()), ISWS(ch))
+ while ((ch = qcchar()), ISWS(ch))
;
return ch;
}
-/*
- * As above but only between \n and #.
- */
-static int
-fastspcg(void)
-{
- int ch, c2;
-
- while ((ch = inch()) == '/' || ch == '%' || ISWS(ch)) {
- if (ch == '%') {
- if ((c2 = inch()) == ':')
- ch = '#'; /* digraphs */
- else
- unch(c2);
- break;
- }
- if (ch == '/') {
- if (Cflag)
- return ch;
- if (fastcmnt(0) == 0)
- break;
- putch(' ');
- } else
- putch(ch);
- }
- return ch;
-}
-
/*
* readin chars and store in buf. Warn about too long names.
*/
ob->buf[ob->cptr++] = ch;
else
putob(ob, ch);
- } while (spechr[ch = inch()] & C_ID);
+ } while (spechr[ch = qcchar()] & C_ID);
ob->buf[ob->cptr] = 0; /* legal */
unch(ch);
return ob->buf+n;
if (p < MAXIDSZ)
idbuf[p] = ch;
p++;
- } while (spechr[ch = inch()] & C_ID);
+ } while (spechr[ch = qcchar()] & C_ID);
idbuf[p] = 0;
unch(ch);
return idbuf;
struct iobuf *
faststr(int bc, struct iobuf *ob)
{
+ struct iobuf *ib = ifiles->ib;
int ch;
if (ob == NULL)
ob = getobuf(BNORMAL);
- incmnt = 1;
+ instr = 1;
putob(ob, bc);
- while ((ch = inc2()) != bc) {
- if (ch == '\n') {
- warning("unterminated literal");
+ for (;;) {
+ if (ib->bsz == ib->cptr)
+ ch = qcchar();
+ else if (ISCQ(ch = ib->buf[ib->cptr]))
+ ch = qcchar();
+ else
+ ib->cptr++;
+ switch (ch) {
+ case '\\':
+ putob(ob, ch);
+ if (ib->cptr == ib->bsz)
+ inpbuf(0);
+ incmnt = 1;
+ putob(ob, qcchar());
incmnt = 0;
+ continue;
+ case '\n':
+ warning("unterminated literal");
+ instr = 0;
unch(ch);
return ob;
}
- if (ch < 0)
- return ob;
- if (ch == '\\') {
- incmnt = 0;
- if (chkucn())
- continue;
- incmnt = 1;
- putob(ob, ch);
- ch = inc2();
- }
putob(ob, ch);
+ if (ch == bc)
+ break;
}
- putob(ob, ch);
ob->buf[ob->cptr] = 0;
- incmnt = 0;
+ instr = 0;
return ob;
}
if ((spechr[ch] & C_DIGIT) == 0) {
/* not digit, dot */
putob(ob, ch);
- ch = inch();
+ ch = qcchar();
}
for (;;) {
putob(ob, ch);
- if ((ch = inch()) < 0)
- return -1;
- if ((spechr[ch] & C_EP)) {
- if ((c2 = inch()) != '-' && c2 != '+') {
- if (c2 >= 0)
+ if ((ch = qcchar()) == 0)
+ return 0;
+ if ((c2 = (ch & 0337)) == 'E' || c2 == 'P') {
+ if ((c2 = qcchar()) != '-' && c2 != '+') {
+ if (c2 > 0)
unch(c2);
break;
}
{
struct iobuf *ob, rbs, *rb = &rbs;
extern struct iobuf pb;
+ struct iobuf *ib = ifiles->ib;
struct symtab *nl;
- int ch, c2, i, nch;
+ int ch, c2;
usch *dp;
#define IDSIZE 128
/* tight loop to find special chars */
/* should use getchar/putchar here */
for (;;) {
- if (ifiles->ib->cptr < ifiles->ib->bsz) {
- ch = ifiles->ib->buf[ifiles->ib->cptr++];
- } else {
- if (inpbuf() > 0)
- continue;
- free(rb->buf);
- return;
- }
-xloop: if (ch < 0) {
- free(rb->buf);
- return; /* EOF */
- }
+ if (ib->cptr < ib->bsz)
+ ch = ib->buf[ib->cptr++];
+ else
+ ch = qcchar();
+xloop: if (ch < 0) ch = 0; /* XXX */
if ((spechr[ch] & C_SPEC) != 0)
break;
putch(ch);
}
- REFILL(2);
- nch = ifiles->ib->buf[ifiles->curptr];
switch (ch) {
+ case 0:
+ free(rb->buf);
+ return;
+
case WARN:
case CONC:
error("bad char passed");
break;
case '/': /* Comments */
- if (nch != '/' && nch != '*') {
- putch(ch);
- continue;
+ ch = qcchar();
+ if (ch == '/' || ch == '*') {
+ if (Cflag == 0) {
+ int n = ifiles->lineno;
+ fastcmnt2(ch);
+ if (n == ifiles->lineno)
+ putch(' '); /* 5.1.1.2 p3 */
+ } else
+ Ccmnt2(putch, ch);
+ } else {
+ putch('/');
+ goto xloop;
}
- if (Cflag == 0) {
- if (fastcmnt(1))
- putch(' '); /* 5.1.1.2 p3 */
- } else
- Ccmnt(putch);
break;
case '\n': /* newlines, for pp directives */
/* take care of leftover \n */
- i = ifiles->escln + 1;
- ifiles->lineno += i;
- ifiles->escln = 0;
- while (i-- > 0)
+ while (ifiles->escln > 0) {
putch('\n');
+ ifiles->escln--;
+ ifiles->lineno++;
+ }
+ putch('\n');
+ ifiles->lineno++;
/* search for a # */
-run: while ((ch = inch()) == '\t' || ch == ' ')
+run: while ((ch = qcchar()) == '\t' || ch == ' ')
putch(ch);
if (ch == '%') {
- if ((c2 = inch()) != ':')
+ if ((c2 = qcchar()) != ':')
unch(c2);
else
ch = '#';
break;
case '?':
- if (nch == '?' && (ch = chktg()))
- goto xloop;
+ if (ib->cptr+1 >= ib->bsz)
+ inpbuf(2);
+ if (ib->buf[ib->cptr] == '?') {
+ ib->cptr++;
+ if ((ch = chktg2(ib->buf[ib->cptr++])))
+ goto xloop;
+ ib->cptr -= 2;
+ }
putch('?');
break;
}
/* FALLTHROUGH */
case '\"': /* strings */
+ if (skpows)
+ cntline();
faststr(ch, &pb);
break;
case '.': /* for pp-number */
- if ((spechr[nch] & C_DIGIT) == 0) {
+ if ((spechr[c2 = qcchar()] & C_DIGIT) == 0) {
putch('.');
- break;
+ goto xloop;
}
+ unch(c2);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
+ if (skpows)
+ cntline();
ch = fastnum(ch, &pb);
goto xloop;
- case 'u':
- if (nch == '8' && ifiles->ib->buf[ifiles->curptr+1] == '\"') {
- putch(ch);
- break;
- }
- /* FALLTHROUGH */
case 'L':
case 'U':
- if (nch == '\"' || nch == '\'') {
+ case 'u':
+ if (ib->cptr+2 >= ib->bsz)
+ inpbuf(2);
+ if ((c2 = ib->buf[ib->cptr]) == '\"' || c2 == '\'') {
putch(ch);
break;
+ } else if (c2 == '8' && ch == 'u' &&
+ ib->buf[ib->cptr+1] == '\"') {
+ ib->cptr++;
+ putstr((usch *)"u8");
+ break;
}
/* FALLTHROUGH */
default:
if ((spechr[ch] & C_ID) == 0)
error("fastscan");
#endif
- ident:
if (flslvl)
error("fastscan flslvl");
rb->cptr = 0;
if ((ob = kfind(nl)) != NULL) {
if (*ob->buf == '-' || *ob->buf == '+')
putch(' ');
+ if (skpows)
+ cntline();
buftobuf(ob, &pb);
if (ob->cptr > 0 &&
(ob->buf[ob->cptr-1] == '-' ||
break;
case '\\':
- if (nch == '\n') {
- ifiles->escln++;
- ifiles->curptr++;
- break;
- }
- if (chkucn()) {
- ch = inch();
- goto ident;
- }
+ ib->buf[--ib->cptr] = '\\';
+ if ((ch = qcchar()) != '\\')
+ goto xloop;
putch('\\');
break;
}
}
-
-/*eof:*/ warning("unexpected EOF");
- putch('\n');
}
/*
Cflag = ifdef = 0;
for (;;) {
- c = inch();
+ c = qcchar();
xloop: if (c == '\n')
break;
if (c == '.') {
putob(rb, '.');
- if ((spechr[c = inch()] & C_DIGIT) == 0)
+ if ((spechr[c = qcchar()] & C_DIGIT) == 0)
goto xloop;
}
if (ISDIGIT(c)) {
continue;
}
if (c == 'L' || c == 'u' || c == 'U') {
- unch(d = inch());
+ unch(d = qcchar());
if (d == '\'') /* discard wide designator */
continue;
}
bufree(ob);
}
} else if (!Pflag) {
+ skpows = 0;
bsheap(&pb, "\n# %d \"%s\"", ifiles->lineno, ifiles->fname);
if (ifiles->idx == SYSINC)
strtobuf((usch *)" 3", &pb);
if (t) {
f("newline expected");
/* ignore rest of line */
- while ((t = inch()) >= 0 && t != '\n')
+ while ((t = qcchar()) > 0 && t != '\n')
;
} else
f("no newline at end of file");
}
/* save line into iobuf */
-static struct iobuf *
+struct iobuf *
savln(void)
{
struct iobuf *ob = getobuf(BNORMAL);
int c;
- while ((c = inch()) != -1) {
+ while ((c = qcchar()) != 0) {
if (c == '\n') {
unch(c);
break;
cpperror(void)
{
struct iobuf *ob = savln();
- error("#error %s", ob->buf);
+ error("#error%s", ob->buf);
bufree(ob);
}
cppwarning(void)
{
struct iobuf *ob = savln();
- error("#warning %s", ob->buf);
+ warning("#warning%s", ob->buf);
bufree(ob);
}
int ch;
putstr((const usch *)"\n#pragma");
- while ((ch = inch()) != '\n' && ch > 0)
+ while ((ch = qcchar()) != '\n' && ch > 0)
putch(ch);
unch(ch);
prtline(1);
cinput(void)
{
- return inch();
+ return qcchar();
}
#define DIR_FLSLVL 001
int ch;
/* just ignore the rest of the line */
- while ((ch = inch()) != -1) {
+ while ((ch = qcchar()) != 0) {
if (ch == '\n') {
unch('\n');
break;
int ch;
for (;;) {
- switch (ch = inch()) {
- case -1:
+ ch = qcchar();
+again: switch (ch) {
+ case 0:
return;
case '\n':
- ifiles->lineno++;
putch('\n');
- if ((ch = fastspcg()) == '#')
+ ifiles->lineno++;
+ while ((ch = qcchar()) == ' ' || ch == '\t')
+ ;
+ if (ch == '#')
return;
- unch(ch);
+ if (ch == '%' && (ch = qcchar()) == ':')
+ return;
+ goto again;
+ case '\'':
+ while ((ch = qcchar()) != '\'')
+ if (ch == '\n')
+ return;
break;
- case '/':
- fastcmnt(0); /* may be around directives */
+ case '\"':
+ instr = 1;
+ while ((ch = qcchar()) != '\"') {
+ switch (ch) {
+ case '\\':
+ incmnt = 1;
+ qcchar();
+ incmnt = 0;
+ break;
+ case '\n':
+ unch(ch);
+ /* FALLTHROUGH */
+ case 0:
+ instr = 0;
+ return;
+ }
+ }
+ instr = 0;
break;
+ case '/':
+ ch = qcchar();
+ if (ch == '/' || ch == '*')
+ fastcmnt2(ch);
+ goto again;
}
}
}
(*ppd[i].fun)();
if (flslvl == 0)
return;
- }else if (ppd[i].flags & DIR_FLSINC)
+ } else if (ppd[i].flags & DIR_FLSINC)
flslvl++;
}
flscan();
-/* $Id: cgram.y,v 1.9 2015/11/24 17:30:20 ragge Exp $ */
+/* $Id: cgram.y,v 1.10 2016/08/09 17:30:26 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
static struct symtab *
init_declarator(NODE *tn, NODE *p, int assign, NODE *a)
{
- int class = glval(tn);
+ int class = (int)glval(tn);
struct symtab *sp;
p = aryfix(p);
extern int prolab;
struct symtab *s, *nsthis;
NODE *q, *typ;
- int class = glval(tp), oclass, ctval;
+ int class = (int)glval(tp), oclass, ctval;
char *c;
/*
con_e(NODE *p)
{
#ifdef WORD_ADDRESSED
- return icons(optim(eve(p)));
+ return (int)icons(optim(eve(p)));
#else
- return icons(optim(rmpconv(eve(p))));
+ return (int)icons(optim(rmpconv(eve(p))));
#endif
}
%{
-/* $Id: scan.l,v 1.7 2016/03/05 15:31:25 ragge Exp $ */
+/* $Id: scan.l,v 1.9 2016/08/07 08:54:57 ragge Exp $ */
/*
* Copyright (c) 2002 Anders Magnusson. All rights reserved.
#include "pass1.h"
#include "cgram.h"
+#define bdebug flexbdebug
+
static NODE *cvtdig(int radix);
static NODE *charcon(void);
static NODE *wcharcon(void);
static void control(int);
static void pragma(void);
int notype, parbal, inattr, parlvl, nodinit, inoso;
+static int dotfile;
static int resw(TWORD, int);
static int namechk(void);
return xbcon(lastcon, NULL, ctype(UNSIGNED));
}
+#ifndef MYDOTFILE
+/*
+ * Get basename and print it as '.file "basename.c"'
+ */
+static void
+printdotfile(char *file)
+{
+ char *p;
+
+ if ((p = strrchr(file, '/')) == NULL)
+ p = file;
+ else
+ p++;
+ printf(PRTPREF "\t.file \"%s\"\n", p);
+}
+#endif
+
void
control(int t)
{
if (gflag)
stabs_file(ftitle);
#endif
+ if (dotfile == 0) {
+ dotfile++;
+ printdotfile(ftitle);
+ }
}
return;
bad:
-/* $Id: trees.c,v 1.21 2016/03/05 15:31:25 ragge Exp $ */
+/* $Id: trees.c,v 1.22 2016/08/09 17:11:57 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
ip->ip_node = va_arg(ap, NODE *);
if (ip->ip_node->n_op == LABEL) {
NODE *p = ip->ip_node;
- ip->ip_lbl = glval(p->n_left);
+ ip->ip_lbl = (int)glval(p->n_left);
ip->type = IP_DEFLAB;
nfree(nfree(p));
}
/* Version string */
#undef VERSSTR
+/* Target string */
+#undef TARGSTR
+
/* Size of wide-character type in chars */
#undef WCHAR_SIZE
arm*) targmach=arm ;;
i?86) targmach=i386 ;;
x86_64) targmach=amd64 ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
esac
i?86) targmach=i386 ;;
powerpc*) targmach=powerpc endian=big ;;
x86_64) targmach=amd64 ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
esac
litebsd*)
targos=litebsd
abi=elf
- wchar_type=USHORT
case "$target_cpu" in
mips*) targmach=mips ;;
esac
altlibdir="c:/mingw/lib"
;;
- minix*)
- targos=minix
- stabs=yes
- case "$target_os" in
- minix3) abi=aout ;;
- minix3.*) abi=elf ;;
- # default to ELF
- *) abi=elf ;;
- esac
- case "$target_cpu" in
- i86) targmach=i86 ;;
- i?86) targmach=i386 ;;
- arm*) targmach=arm ;;
- x86_64) targmach=amd64 ;;
- esac
- ;;
+ minix*)
+ targos=minix
+ targosver=`uname -v`
+ stabs=yes
+ case "$targosver" in
+ # explicit setting
+ 1.*)
+ # pcc works for 3.1.6
+ # not tested for 3.1.7 and 3.1.8
+ targosver=3.1.x
+ abi=aout ;;
+ *3*)
+ # Minix switched to ELF with 3.2
+ targosver=3.2+
+ abi=elf ;;
+ *)
+ # default to elf
+ targosver=unknown
+ abi=elf ;;
+ esac
+ case "$target_cpu" in
+ i86) targmach=i86 ;;
+ i?86) targmach=i386 ;;
+ arm*) targmach=arm ;;
+ x86_64) targmach=amd64 ;;
+ esac
+ ;;
mirbsd*)
targos=mirbsd
arm*) targmach=arm ;;
i?86) targmach=i386 ;;
m68k*) targmach=m68k endian=big ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
pdp10) targmach=pdp10 ;;
case "$target_cpu" in
i?86) targmach=i386 ;;
vax) targmach=vax ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
powerpc) targmach=powerpc endian=big ;;
sparc64) targmach=sparc64 endian=big ;;
m68k) targmach=m68k endian=big ;;
pcc_minorminor=`echo $PACKAGE_VERSION | awk -F. '{print $3}'`
test -n "$MPVERSION" && MPVERSION=", $MPVERSION"
versstr="\"$PACKAGE_STRING `cat $srcdir/DATESTAMP` for $target$MPVERSION\""
+targstr="\"$target$MPVERSION\""
cat >>confdefs.h <<_ACEOF
_ACEOF
+cat >>confdefs.h <<_ACEOF
+#define TARGSTR $targstr
+_ACEOF
+
+
ac_config_files="$ac_config_files Makefile cc/Makefile cc/cc/Makefile cc/cpp/Makefile cc/ccom/Makefile cc/cxxcom/Makefile cc/driver/Makefile f77/Makefile f77/f77/Makefile f77/fcom/Makefile"
cat >confcache <<\_ACEOF
arm*) targmach=arm ;;
i?86) targmach=i386 ;;
x86_64) targmach=amd64 ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
esac
i?86) targmach=i386 ;;
powerpc*) targmach=powerpc endian=big ;;
x86_64) targmach=amd64 ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
esac
litebsd*)
targos=litebsd
abi=elf
- wchar_type=USHORT
case "$target_cpu" in
mips*) targmach=mips ;;
esac
altlibdir="c:/mingw/lib"
;;
- minix*)
- targos=minix
- stabs=yes
- case "$target_os" in
- minix3) abi=aout ;;
- minix3.*) abi=elf ;;
- # default to ELF
- *) abi=elf ;;
- esac
- case "$target_cpu" in
- i86) targmach=i86 ;;
- i?86) targmach=i386 ;;
- arm*) targmach=arm ;;
- x86_64) targmach=amd64 ;;
- esac
- ;;
+ minix*)
+ targos=minix
+ targosver=`uname -v`
+ stabs=yes
+ case "$targosver" in
+ # explicit setting
+ 1.*)
+ # pcc works for 3.1.6
+ # not tested for 3.1.7 and 3.1.8
+ targosver=3.1.x
+ abi=aout ;;
+ *3*)
+ # Minix switched to ELF with 3.2
+ targosver=3.2+
+ abi=elf ;;
+ *)
+ # default to elf
+ targosver=unknown
+ abi=elf ;;
+ esac
+ case "$target_cpu" in
+ i86) targmach=i86 ;;
+ i?86) targmach=i386 ;;
+ arm*) targmach=arm ;;
+ x86_64) targmach=amd64 ;;
+ esac
+ ;;
mirbsd*)
targos=mirbsd
arm*) targmach=arm ;;
i?86) targmach=i386 ;;
m68k*) targmach=m68k endian=big ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
mipseb) targmach=mips endian=big ;;
mips*) targmach=mips ;;
pdp10) targmach=pdp10 ;;
case "$target_cpu" in
i?86) targmach=i386 ;;
vax) targmach=vax ;;
+ mips64el) targmach=mips64 ;;
+ mips64) targmach=mips64 endian=big ;;
powerpc) targmach=powerpc endian=big ;;
sparc64) targmach=sparc64 endian=big ;;
m68k) targmach=m68k endian=big ;;
pcc_minorminor=`echo $PACKAGE_VERSION | awk -F. '{print $3}'`
test -n "$MPVERSION" && MPVERSION=", $MPVERSION"
versstr="\"$PACKAGE_STRING `cat $srcdir/DATESTAMP` for $target$MPVERSION\""
+targstr="\"$target$MPVERSION\""
AC_DEFINE_UNQUOTED(PCC_MAJOR, $pcc_major, [Major version no])
AC_DEFINE_UNQUOTED(PCC_MINOR, $pcc_minor, [Minor version no])
AC_DEFINE_UNQUOTED(PCC_MINORMINOR, $pcc_minorminor, [Minor minor version no])
AC_DEFINE_UNQUOTED(VERSSTR, $versstr, [Version string])
+AC_DEFINE_UNQUOTED(TARGSTR, $targstr, [Target string])
AC_CONFIG_FILES([Makefile
cc/Makefile
-/* $Id: optim2.c,v 1.92 2015/11/17 19:19:40 ragge Exp $ */
+/* $Id: optim2.c,v 1.93 2016/08/09 17:14:58 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
case GOTO:
if (q->n_left->n_op == ICON) {
p->op = JBR;
- p->labno = getlval(q->n_left);
+ p->labno = (int)getlval(q->n_left);
} else
p->op = STMT;
break;
case CBRANCH:
p->op = CBR;
- p->labno = getlval(q->n_right);
+ p->labno = (int)getlval(q->n_right);
break;
case ASSIGN:
/* remove ASSIGN to self for regs */
-/* $Id: ccconfig.h,v 1.6 2014/12/24 08:43:28 plunky Exp $ */
+/* $Id: ccconfig.h,v 1.7 2016/05/15 08:13:53 ragge Exp $ */
/*
* Escrit per Antoine Leca pel projecte PCC, 2011-03.
* Copyright (C) 2011 Anders Magnusson (ragge@ludd.luth.se).
#define CRTEND_T 0
#define CRTI 0
-#define CRTN "-lend"
+#define CRTN "end.a"
+
+#define DEFLIBS {"-lc", "-lpccsoftfloat", "-lpcc", "-lc", NULL }
#if defined(mach_i386)
#define CPPMDADD { "-D__i386", "-D__i386__", \
-/* $Id: ccconfig.h,v 1.31 2014/12/24 08:43:29 plunky Exp $ */
+/* $Id: ccconfig.h,v 1.32 2016/07/06 07:49:48 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
#define STARTLABEL "_start"
#elif defined(mach_mips)
#define CPPMDADD { "-D__mips__", NULL, }
+#elif defined(mach_mips64)
+#ifdef TARGET_BIG_ENDIAN
+#define CPPMDADD { "-D__MIPSEB__", "-D__mips__", "-D__mips64__", NULL, }
+#else
+#define CPPMDADD { "-D__MIPSEL__", "-D__mips__", "-D__mips64__", "-D__mipsel__", "-D__mips64el__", NULL, }
+#endif
#elif defined(mach_pdp10)
#define CPPMDADD { "-D__pdp10__", NULL, }
#elif defined(mach_powerpc)
-/* $Id: ccconfig.h,v 1.15 2014/12/24 08:43:29 plunky Exp $ */
+/* $Id: ccconfig.h,v 1.18 2016/07/10 08:18:28 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
#if defined(mach_amd64)
#define CPPMDADD { "-D__amd64__", NULL, }
+#define DEFLIBS { "-lc", NULL }
+#define PCC_EARLY_SETUP { kflag = 1; }
#elif defined(mach_i386)
#define CPPMDADD { "-D__i386__", NULL, }
#elif defined(mach_vax)
#elif defined(mach_m68k)
#define CPPMDADD { "-D__mc68000__", "-D__mc68020__", "-D__m68k__", NULL }
#define STARTLABEL "_start"
+#elif defined(mach_mips64)
+#ifdef TARGET_BIG_ENDIAN
+#define CPPMDADD { "-D__MIPSEB__", "-D__mips__", "-D__mips64__", NULL }
+#else
+#define CPPMDADD { "-D__MIPSEL__", "-D__mips__", "-D__mipsel__", "-D__mips64__", "-D__mips64el__", NULL }
+#endif
+#define DEFLIBS { "-lc", NULL }
+#define PCC_EARLY_SETUP { kflag = 1; }
#else
#error defines for arch missing
#endif