/* $Header$ */ /* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ /* S T A C K _ C H A N G E . C */ #include #include "../share/types.h" #include "../share/debug.h" #include "../share/global.h" #include "../../../h/em_spec.h" #include "../../../h/em_mnem.h" #include "pop_push.h" #define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && TYPE(l)==OPSHORT) int stack_change(l,sign) line_p l; char sign; { /* Interpret the string in the third column of the em_table file */ char *s; bool argdef; short arg; int sum = 0; line_p p = PREV(l); line_p pp = (p == (line_p) 0 ? (line_p) 0 : PREV(p)); short i = INSTR(l); if (i < sp_fmnem || i > sp_lmnem) { return 0; } else { if (TYPE(l) == OPSHORT) { arg = SHORT(l); if (arg < ws) { /* E.g. a LOI 1 loads word-size bytes, * not 1 byte! */ arg = ws; } argdef = TRUE; } else { argdef = FALSE; } } s = pop_push[i]; if (*s == '0') return 0; while (*s != '\0') { if (*s++ == sign) { switch(*s) { case 'w': sum += ws; break; case 'd': sum += 2 * ws; break; case 'p': sum += ps; break; case 'a': if (!argdef) return -1; sum += arg; break; case 'x': if (IS_LOC(p)) { sum += SHORT(p); break; } else { return -1; } case 'y': if (IS_LOC(pp)) { sum += SHORT(pp); break; } else { return -1; } case '?': return -1; default: assert(FALSE); } } s++; } return sum; } line_change(l,ok_out,pop_out,push_out) line_p l; bool *ok_out; int *pop_out,*push_out; { short pop,push; pop = stack_change(l,'-'); push = stack_change(l,'+'); *ok_out = (pop != -1 && push != -1); *pop_out = pop; *push_out = push; }