const char *qpu_r(uint32_t ra, uint32_t rb, uint32_t adda, uint32_t op, int rotator) { if (op == 13) { if (rb<48) { if (adda==6) return banka_r[ra]; if (adda==7) return imm[rb]; } else { if ((adda<6) && rotator) { char *tmp = tmpalloc(32); sprintf(tmp, "%s%s", acc_names[adda], imm[rb]); return tmp; } if ((adda==6) && rotator) { char *tmp = tmpalloc(32); sprintf(tmp, "%s%s", banka_r[ra], imm[rb]); return tmp; } if ((adda==7) && rotator) { return "err?"; } } } if (adda==6) return banka_r[ra]; if (adda==7) return bankb_r[rb]; return acc_names[adda]; }
/* EFUN: filter (array part) Runs all elements of an array through fun and returns an array holding those elements that fun returned 1 for. */ struct vector * filter_arr(struct vector *p, struct closure *fun) { struct vector *r; char *flags; int cnt,res; if (p->size<1) return allocate_array(0); res = 0; flags = tmpalloc((size_t)p->size + 1); for (cnt = 0; cnt < p->size; cnt++) { push_svalue(&p->item[cnt]); (void)call_var(1, fun); if (sp->type == T_NUMBER && sp->u.number) { flags[cnt] = 1; res++; } else flags[cnt] = 0; pop_stack(); } r = allocate_array(res); for (cnt = res = 0; res < r->size && cnt < p->size; cnt++) { if (flags[cnt]) assign_svalue_no_free(&r->item[res++], &p->item[cnt]); } /* tmpfree(flags); */ return r; }
sNode_t gen(sNode_t p) { sNode_t head, *last; for (last = &head; p; p = p->link) last = linearize(p, last, 0); for (p = head; p; p = p->x.next) tmpalloc(p); return head; }
/* * Duplicate a string onto the temporary heap. */ char * tmpstrdup(char *str) { int len; len = strlen(str) + 1; return memcpy(tmpalloc(len), str, len); }
void * tmpcalloc(int size) { void *rv; rv = tmpalloc(size); memset(rv, 0, size); return rv; }
char * tmpstring_copy(char *cp) { char *xp; xp = tmpalloc(strlen(cp) + 1); (void)strcpy(xp, cp); return xp; }
static char * mk3str(char *s1, char *s2, char *s3) { int len = strlen(s1) + strlen(s2) + strlen(s3) + 1; char *sd; sd = tmpalloc(len); strlcpy(sd, s1, len); strlcat(sd, s2, len); strlcat(sd, s3, len); return sd; }
static int put_in(struct unique **ulist, struct svalue *marker, struct svalue *elem) { struct unique *llink, *slink, *tlink; int cnt,fixed; llink = *ulist; cnt = 0; fixed = 0; while (llink) { if ((!fixed) && (equal_svalue(marker, &(llink->mark)))) { for (tlink = llink; tlink->same; tlink = tlink->same) (tlink->count)++; (tlink->count)++; slink = (struct unique *) tmpalloc(sizeof(struct unique)); slink->count = 1; assign_svalue_no_free(&slink->mark, marker); slink->val = elem; slink->same = 0; slink->next = 0; tlink->same = slink; fixed = 1; /* We want the size of the list so do not break here */ } llink = llink->next; cnt++; } if (fixed) return cnt; llink = (struct unique *) tmpalloc(sizeof(struct unique)); llink->count = 1; assign_svalue_no_free(&llink->mark, marker); llink->val = elem; llink->same = 0; llink->next = *ulist; *ulist = llink; return cnt + 1; }
/* * cause the alignment to become a multiple of n */ void defalign(int n) { #if 0 char *s; n /= SZCHAR; if (lastloc == PROG || n == 1) return; s = (isinlining ? permalloc(40) : tmpalloc(40)); sprintf(s, ".align %d", n); send_passt(IP_ASM, s); #endif }
/* * Return NANs, if reasonable. */ static NODE * builtin_nanx(const struct bitable *bt, NODE *a) { if (a == NULL || a->n_op == CM) { uerror("%s bad argument", bt->name); a = bcon(0); } else if (a->n_op == STRING && *a->n_name == '\0') { a->n_op = FCON; a->n_type = bt->rt; a->n_dcon = tmpalloc(sizeof(union flt)); memcpy(&((union flt *)a->n_dcon)->fp, nLDOUBLE, sizeof(long double)); } else a = binhelp(eve(a), bt->rt, &bt->name[10]); return a; }
void myp2tree(NODE *p) { struct symtab *sp; NODE *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); r->n_sp = lookup(addname("__nova_rbyte"), SNORMAL); if (r->n_sp->sclass == SNULL) { r->n_sp->sclass = EXTERN; r->n_sp->stype = INCREF(p->n_type)+(FTN-PTR); } r->n_type = r->n_sp->stype; r = clocal(r); r = optim(buildtree(CALL, r, l)); *p = *r; nfree(r); break; case FCON: sp = tmpalloc(sizeof(struct symtab)); sp->sclass = STATIC; sp->sap = 0; sp->slevel = 1; /* fake numeric label */ sp->soffset = getlab(); sp->sflags = 0; sp->stype = p->n_type; sp->squal = (CON >> TSHIFT); defloc(sp); ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p); p->n_op = NAME; p->n_lval = 0; p->n_sp = sp; } }
static int string(char *str) { char *p; if (!*str) { str = "\"\""; } p = tmpalloc(strlen(str) + 1); yylval.string = p; for (str++; str[0] && str[1] ; str++, p++) { /* Copy the similar one to here /JH */ if (str[0] == '\\') { if (str[1] == 'n') { *p = '\n'; } else if (str[1] == 't') { *p = '\t'; } else if (str[1] == 'r') { *p = '\r'; } else if (str[1] == 'b') { *p = '\b'; } else if (str[1] == 'a') { *p = '\a'; } else if (str[1] == 'v') { *p = '\v'; } else if (str[1] == '"' || str[1] == '\\' || str[1] == '\'') { *p = str[1]; } else { lexwarning("Bad string escape sequence."); *p = str[1]; } str++; } else *p = *str; } *p = '\0'; return F_STRING; }
int yylex(void) { int r; if (keep1.token != -47) { /* * something in keep buffer. shift it out. */ r = keep1.token; current_line = keep1.line; yylval = keep1.lval; keep1 = keep2; keep2 = keep3; keep3.token = -47; return r; } yytext[0] = 0; /* * see if the next token is a string */ if ((r = yylex1()) == F_STRING) { keep4.lval = yylval; keep4.line = current_line; yytext[0] = 0; r = yylex1(); for (;;) { keep1.line = current_line; keep1.lval = yylval; if (r != '+') { /* * 1:string 2:non-'+' * save 2, return 1 */ keep1.token = r; yylval = keep4.lval; current_line = keep4.line; return F_STRING; } yytext[0] = 0; r = yylex1(); keep2.line = current_line; keep2.lval = yylval; if (r != F_STRING) { /* * 1:string 2:'+' 3:non-string * save 2 and 3, return 1 */ keep1.token = '+'; keep2.token = r; current_line = keep4.line; yylval = keep4.lval; return F_STRING; } yytext[0] = 0; r = yylex1(); keep3.line = current_line; keep3.lval = yylval; if (r == '[' || r == F_ARROW) { /* * 1:string 2:'+' 3:string 4:[-> * save 2, 3, 4, return 1 */ keep1.token = '+'; keep2.token = F_STRING; keep3.token = r; current_line = keep4.line; yylval = keep4.lval; return F_STRING; } /* * concatenate string constants */ keep3.lval.string = tmpalloc(strlen(keep4.lval.string) + strlen(keep2.lval.string) + 1); (void)strcpy(keep3.lval.string, keep4.lval.string); (void)strcat(keep3.lval.string, keep2.lval.string); keep4.line = keep2.line; keep4.lval.string = keep3.lval.string; } } /* (void)fprintf(stderr, "lex=%d(%s) ", r, yytext);*/ return r; }
/* clocal() is called to do local transformations on * an expression tree preparitory to its being * written out in intermediate code. * * the major essential job is rewriting the * automatic variables and arguments in terms of * REG and OREG nodes * conversion ops which are not necessary are also clobbered here * in addition, any special features (such as rewriting * exclusive or) are easily handled here as well */ NODE * clocal(NODE *p) { register struct symtab *q; register NODE *r, *l; register int o; register int m; TWORD t; #ifdef PCC_DEBUG if (xdebug) { printf("clocal: %p\n", p); fwalk(p, eprint, 0); } #endif 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); slval(r, 0); r->n_rval = FPREG; p = stref(block(STREF, r, p, 0, 0, 0)); break; case USTATIC: if (kflag == 0) break; /* FALLTHROUGH */ case STATIC: #ifdef TLS if (q->sflags & STLS) { p = tlsref(p); break; } #endif break; case REGISTER: p->n_op = REG; slval(p, 0); p->n_rval = q->soffset; break; case EXTERN: case EXTDEF: if (q->sflags & STLS) { p = tlsref(p); break; } if (kflag == 0 || statinit) break; if (blevel > 0) p = picext(p); break; } break; case UCALL: case USTCALL: /* For now, always clear eax */ l = block(REG, NIL, NIL, INT, 0, 0); regno(l) = RAX; p->n_right = clocal(buildtree(ASSIGN, l, bcon(0))); p->n_op -= (UCALL-CALL); break; case SCONV: /* Special-case shifts */ if (p->n_type == LONG && (l = p->n_left)->n_op == LS && l->n_type == INT && l->n_right->n_op == ICON) { p->n_left = l->n_left; p = buildtree(LS, p, l->n_right); nfree(l); break; } l = p->n_left; /* Float conversions may need extra casts */ if (p->n_type == FLOAT || p->n_type == DOUBLE || p->n_type == LDOUBLE) { if (l->n_type < INT || l->n_type == BOOL) { p->n_left = block(SCONV, l, NIL, ISUNSIGNED(l->n_type) ? UNSIGNED : INT, l->n_df, l->n_ap); break; } } if (p->n_type == l->n_type) { nfree(p); return l; } if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 && tsize(p->n_type, p->n_df, p->n_ap) == tsize(l->n_type, l->n_df, l->n_ap)) { 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_op != COMOP && l->n_op != QUEST && l->n_op != ASSIGN) { l->n_type = p->n_type; nfree(p); return l; } o = l->n_op; m = p->n_type; if (o == ICON) { CONSZ val = glval(l); if (ISPTR(l->n_type) && !nncon(l)) break; /* cannot convert named pointers */ if (!ISPTR(m)) /* Pointers don't need to be conv'd */ switch (m) { case BOOL: val = nncon(l) ? (val != 0) : 1; slval(l, val); l->n_sp = NULL; break; case CHAR: slval(l, (char)val); break; case UCHAR: slval(l, val & 0377); break; case SHORT: slval(l, (short)val); break; case USHORT: slval(l, val & 0177777); break; case UNSIGNED: slval(l, val & 0xffffffff); break; case INT: slval(l, (int)val); break; case LONG: case LONGLONG: slval(l, (long long)val); break; case ULONG: case ULONGLONG: slval(l, val); break; case VOID: break; case LDOUBLE: case DOUBLE: case FLOAT: l->n_op = FCON; l->n_dcon = tmpalloc(sizeof(union flt)); ((union flt *)l->n_dcon)->fp = val; break; default: cerror("unknown type %d", m); } l->n_type = m; l->n_ap = NULL; nfree(p); return l; } else if (l->n_op == FCON) { CONSZ lv; if (p->n_type == BOOL) lv = !FLOAT_ISZERO(((union flt *)l->n_dcon)); else { FLOAT_FP2INT(lv, ((union flt *)l->n_dcon), m); } slval(l, lv); l->n_sp = NULL; l->n_op = ICON; l->n_type = m; l->n_ap = NULL; nfree(p); return clocal(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_ap); 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 = makety(p->n_left, INT, 0, 0, 0); p->n_right = makety(p->n_right, INT, 0, 0, 0); p = makety(p, p->n_type, 0, 0, 0); p->n_left->n_type = INT; break; 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); t = p->n_type; if (ISITY(t)) t = t - (FIMAG-FLOAT); p->n_left->n_rval = p->n_left->n_type == BOOL ? RETREG(CHAR) : RETREG(t); break; case LS: case RS: /* shift count must be in a char */ if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR) break; p->n_right = makety(p->n_right, CHAR, 0, 0, 0); break; } #ifdef PCC_DEBUG if (xdebug) { printf("clocal end: %p\n", p); fwalk(p, eprint, 0); } #endif return(p); }