1994-06-24 11:31:16 +00:00
|
|
|
/* $Id$ */
|
1987-03-09 19:15:41 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1984-11-26 13:58:05 +00:00
|
|
|
|
|
|
|
/* V A L U E N U M B E R I N G M E T H O D */
|
|
|
|
|
1991-03-05 12:16:17 +00:00
|
|
|
#include <em_mnem.h>
|
1984-11-26 13:58:05 +00:00
|
|
|
#include "../share/types.h"
|
|
|
|
#include "../share/global.h"
|
|
|
|
#include "../share/debug.h"
|
2019-02-08 23:02:41 +00:00
|
|
|
#include "../share/utils.h"
|
1984-11-26 13:58:05 +00:00
|
|
|
#include "cs.h"
|
|
|
|
#include "cs_alloc.h"
|
|
|
|
#include "cs_aux.h"
|
|
|
|
#include "cs_entity.h"
|
|
|
|
#include "cs_avail.h"
|
|
|
|
#include "cs_stack.h"
|
|
|
|
#include "cs_kill.h"
|
|
|
|
#include "cs_partit.h"
|
|
|
|
#include "cs_getent.h"
|
2018-03-05 18:32:06 +00:00
|
|
|
#include "cs_profit.h"
|
1984-11-26 13:58:05 +00:00
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void push_entity(entity_p enp, line_p lfirst)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
/* Build token and Push it. */
|
|
|
|
|
|
|
|
struct token tk;
|
|
|
|
|
|
|
|
tk.tk_vn = enp->en_vn;
|
|
|
|
tk.tk_size = enp->en_size;
|
|
|
|
tk.tk_lfirst = lfirst;
|
|
|
|
Push(&tk);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void put_expensive_load(bblock_p bp, line_p lnp, line_p lfirst,
|
|
|
|
entity_p enp)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
|
|
|
av.av_instr = INSTR(lnp);
|
|
|
|
av.av_size = enp->en_size;
|
|
|
|
av.av_operand = enp->en_vn;
|
|
|
|
|
|
|
|
ocp = newoccur(lfirst, lnp, bp);
|
|
|
|
|
|
|
|
av_enter(&av, ocp, EXPENSIVE_LOAD);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void put_aar(bblock_p bp, line_p lnp, line_p lfirst, entity_p enp)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
Check AAR earlier to prevent LOI/STI unknown size.
In ego, the CS phase may convert a LAR/SAR to AAR LOI/STI so it can
optimize multiple occurrences of AAR of the same array element. This
conversion should not happen if it would LOI/STI a large or unknown
size.
cs_profit.c okay_lines() checked the size of each occurrence of AAR
except the first. If the first AAR was the implicit AAR in a LAR/SAR,
then the conversion happened without checking the size. For unknown
size, this made a bad LOI -1 or STI -1. Fix by checking the size
earlier: if a LAR/SAR has a bad size, then don't enter it as an AAR.
This Modula-2 code showed the bug. Given M.def:
DEFINITION MODULE M;
TYPE S = SET OF [0..95];
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER);
END M.
and M.mod:
(*$R-*) IMPLEMENTATION MODULE M;
FROM SYSTEM IMPORT ADDRESS, ADR;
PROCEDURE G(s: S; p, q: ADDRESS; t: S); BEGIN
s := s; p := p; q := q; t := t;
END G;
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER); BEGIN
G(a[i + j], ADR(a[i + j]), ADR(a[i + j]), a[i + j])
END F;
END M.
then the bug caused an error:
$ ack -mlinuxppc -O3 -c.e M.mod
/tmp/Ack_b357d.g, line 57: Argument range error
The bug had put LOI -1 in the code, then em_decode got an error
because -1 is out of range for LOI.
Procedure F has 4 occurrences of `a[i + j]`. The size of `a[i + j]`
is 96 bits, or 12 bytes, but the EM code hides the size in an array
descriptor, so the size is unknown to CS. The pragma `(*$R-*)`
disables a range check on `i + j` so CS can work. EM uses AAR for the
2 `ADR(a[i + j])` and LAR for the other 2 `a[i + j]`. EM pushes the
arguments to G in reverse order, so the last `a[i + j]` in Modula-2 is
the first LAR in EM.
CS found 4 occurrences of AAR. The first AAR was an implicit AAR in
LAR. Because of the bug, CS converted this LAR 4 to AAR 4 LOI -1.
2018-03-02 21:06:21 +00:00
|
|
|
/* Enter the implicit AAR in a LAR or SAR, where enp points to
|
|
|
|
* the ENARRELEM, and AAR computes its address.
|
|
|
|
*/
|
1984-11-26 13:58:05 +00:00
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
Check AAR earlier to prevent LOI/STI unknown size.
In ego, the CS phase may convert a LAR/SAR to AAR LOI/STI so it can
optimize multiple occurrences of AAR of the same array element. This
conversion should not happen if it would LOI/STI a large or unknown
size.
cs_profit.c okay_lines() checked the size of each occurrence of AAR
except the first. If the first AAR was the implicit AAR in a LAR/SAR,
then the conversion happened without checking the size. For unknown
size, this made a bad LOI -1 or STI -1. Fix by checking the size
earlier: if a LAR/SAR has a bad size, then don't enter it as an AAR.
This Modula-2 code showed the bug. Given M.def:
DEFINITION MODULE M;
TYPE S = SET OF [0..95];
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER);
END M.
and M.mod:
(*$R-*) IMPLEMENTATION MODULE M;
FROM SYSTEM IMPORT ADDRESS, ADR;
PROCEDURE G(s: S; p, q: ADDRESS; t: S); BEGIN
s := s; p := p; q := q; t := t;
END G;
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER); BEGIN
G(a[i + j], ADR(a[i + j]), ADR(a[i + j]), a[i + j])
END F;
END M.
then the bug caused an error:
$ ack -mlinuxppc -O3 -c.e M.mod
/tmp/Ack_b357d.g, line 57: Argument range error
The bug had put LOI -1 in the code, then em_decode got an error
because -1 is out of range for LOI.
Procedure F has 4 occurrences of `a[i + j]`. The size of `a[i + j]`
is 96 bits, or 12 bytes, but the EM code hides the size in an array
descriptor, so the size is unknown to CS. The pragma `(*$R-*)`
disables a range check on `i + j` so CS can work. EM uses AAR for the
2 `ADR(a[i + j])` and LAR for the other 2 `a[i + j]`. EM pushes the
arguments to G in reverse order, so the last `a[i + j]` in Modula-2 is
the first LAR in EM.
CS found 4 occurrences of AAR. The first AAR was an implicit AAR in
LAR. Because of the bug, CS converted this LAR 4 to AAR 4 LOI -1.
2018-03-02 21:06:21 +00:00
|
|
|
assert(INSTR(lnp) == op_lar || INSTR(lnp) == op_sar);
|
1984-11-26 13:58:05 +00:00
|
|
|
assert(enp->en_kind == ENARRELEM);
|
|
|
|
av.av_instr = op_aar;
|
|
|
|
av.av_size = ps;
|
|
|
|
av.av_ofirst = enp->en_arbase;
|
|
|
|
av.av_osecond = enp->en_index;
|
|
|
|
av.av_othird = enp->en_adesc;
|
|
|
|
|
Check AAR earlier to prevent LOI/STI unknown size.
In ego, the CS phase may convert a LAR/SAR to AAR LOI/STI so it can
optimize multiple occurrences of AAR of the same array element. This
conversion should not happen if it would LOI/STI a large or unknown
size.
cs_profit.c okay_lines() checked the size of each occurrence of AAR
except the first. If the first AAR was the implicit AAR in a LAR/SAR,
then the conversion happened without checking the size. For unknown
size, this made a bad LOI -1 or STI -1. Fix by checking the size
earlier: if a LAR/SAR has a bad size, then don't enter it as an AAR.
This Modula-2 code showed the bug. Given M.def:
DEFINITION MODULE M;
TYPE S = SET OF [0..95];
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER);
END M.
and M.mod:
(*$R-*) IMPLEMENTATION MODULE M;
FROM SYSTEM IMPORT ADDRESS, ADR;
PROCEDURE G(s: S; p, q: ADDRESS; t: S); BEGIN
s := s; p := p; q := q; t := t;
END G;
PROCEDURE F(a: ARRAY OF S; i, j: INTEGER); BEGIN
G(a[i + j], ADR(a[i + j]), ADR(a[i + j]), a[i + j])
END F;
END M.
then the bug caused an error:
$ ack -mlinuxppc -O3 -c.e M.mod
/tmp/Ack_b357d.g, line 57: Argument range error
The bug had put LOI -1 in the code, then em_decode got an error
because -1 is out of range for LOI.
Procedure F has 4 occurrences of `a[i + j]`. The size of `a[i + j]`
is 96 bits, or 12 bytes, but the EM code hides the size in an array
descriptor, so the size is unknown to CS. The pragma `(*$R-*)`
disables a range check on `i + j` so CS can work. EM uses AAR for the
2 `ADR(a[i + j])` and LAR for the other 2 `a[i + j]`. EM pushes the
arguments to G in reverse order, so the last `a[i + j]` in Modula-2 is
the first LAR in EM.
CS found 4 occurrences of AAR. The first AAR was an implicit AAR in
LAR. Because of the bug, CS converted this LAR 4 to AAR 4 LOI -1.
2018-03-02 21:06:21 +00:00
|
|
|
/* Before we enter an available AAR, we must check whether we
|
|
|
|
* may convert this LAR/SAR to AAR LOI/STI. This is so we
|
|
|
|
* don't LOI/STI a large or unknown size.
|
|
|
|
*/
|
|
|
|
if (may_become_aar(&av)) {
|
|
|
|
ocp = newoccur(lfirst, lnp, bp);
|
|
|
|
av_enter(&av, ocp, TERNAIR_OP);
|
|
|
|
}
|
1984-11-26 13:58:05 +00:00
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void push_avail(avail_p avp, line_p lfirst)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
struct token tk;
|
|
|
|
|
|
|
|
tk.tk_vn = avp->av_result;
|
|
|
|
tk.tk_size = avp->av_size;
|
|
|
|
tk.tk_lfirst = lfirst;
|
|
|
|
Push(&tk);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void push_unair_op(bblock_p bp, line_p lnp, token_p tkp1)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
|
|
|
av.av_instr = INSTR(lnp);
|
|
|
|
av.av_size = avsize(lnp);
|
|
|
|
av.av_operand = tkp1->tk_vn;
|
|
|
|
|
|
|
|
ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
|
|
|
|
|
|
|
|
push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void push_binair_op(bblock_p bp, line_p lnp, token_p tkp1, token_p tkp2)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
|
|
|
av.av_instr = INSTR(lnp);
|
|
|
|
av.av_size = avsize(lnp);
|
|
|
|
av.av_oleft = tkp1->tk_vn;
|
|
|
|
av.av_oright = tkp2->tk_vn;
|
|
|
|
|
|
|
|
ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
|
|
|
|
|
|
|
|
push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void push_ternair_op(bblock_p bp, line_p lnp, token_p tkp1,
|
|
|
|
token_p tkp2, token_p tkp3)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
|
|
|
av.av_instr = INSTR(lnp);
|
|
|
|
av.av_size = avsize(lnp);
|
|
|
|
av.av_ofirst = tkp1->tk_vn;
|
|
|
|
av.av_osecond = tkp2->tk_vn;
|
|
|
|
av.av_othird = tkp3->tk_vn;
|
|
|
|
|
|
|
|
ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
|
|
|
|
|
|
|
|
push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst);
|
|
|
|
}
|
|
|
|
|
2018-03-05 18:32:06 +00:00
|
|
|
STATIC void push_remainder(bblock_p bp, line_p lnp, token_p tkp1, token_p tkp2)
|
|
|
|
{
|
|
|
|
/* Enter the implicit division tkp1 / tkp2,
|
|
|
|
* then push the remainder tkp1 % tkp2.
|
|
|
|
*/
|
|
|
|
struct avail av;
|
|
|
|
occur_p ocp;
|
|
|
|
|
|
|
|
assert(INSTR(lnp) == op_rmi || INSTR(lnp) == op_rmu);
|
|
|
|
av.av_size = avsize(lnp);
|
|
|
|
av.av_oleft = tkp1->tk_vn;
|
|
|
|
av.av_oright = tkp2->tk_vn;
|
|
|
|
|
|
|
|
/* Check whether we may convert RMI/RMU to DVI/DVU. */
|
|
|
|
if (may_become_dv()) {
|
|
|
|
/* The division is DVI in RMI, or DVU in RMU. */
|
|
|
|
av.av_instr = (INSTR(lnp) == op_rmi ? op_dvi : op_dvu);
|
|
|
|
|
|
|
|
/* In postfix, a b % becomes a b a b / * -. We must
|
|
|
|
* keep a and b on the stack, so the first instruction
|
|
|
|
* to eliminate is lnp, not tkp1->l_first.
|
|
|
|
*/
|
|
|
|
ocp = newoccur(lnp, lnp, bp);
|
|
|
|
av_enter(&av, ocp, BINAIR_OP);
|
|
|
|
}
|
|
|
|
|
|
|
|
av.av_instr = INSTR(lnp);
|
|
|
|
ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
|
|
|
|
push_avail(av_enter(&av, ocp, REMAINDER), tkp1->tk_lfirst);
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void fiddle_stack(line_p lnp)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
/* The instruction in lnp does something to the valuenumber-stack. */
|
|
|
|
|
|
|
|
struct token dummy;
|
|
|
|
offset size;
|
|
|
|
|
|
|
|
/* Partly initialize dummy. */
|
|
|
|
dummy.tk_lfirst = lnp;
|
|
|
|
|
|
|
|
switch (INSTR(lnp)) {
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
|
|
|
break;
|
|
|
|
case op_lor:
|
|
|
|
dummy.tk_vn = newvalnum(); dummy.tk_size = ps;
|
|
|
|
Push(&dummy);
|
|
|
|
break;
|
|
|
|
case op_asp:
|
|
|
|
if ((size = off_set(lnp)) > 0) {
|
|
|
|
Pop(&dummy, size);
|
|
|
|
} else {
|
|
|
|
dummy.tk_vn = newvalnum();
|
|
|
|
dummy.tk_size = size;
|
|
|
|
Push(&dummy);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case op_dup:
|
|
|
|
Dup(lnp);
|
|
|
|
break;
|
|
|
|
case op_ass:
|
|
|
|
case op_dus:
|
|
|
|
case op_exg:
|
|
|
|
case op_los:
|
|
|
|
/* Don't waste effort. */
|
|
|
|
clr_stack();
|
|
|
|
break;
|
|
|
|
case op_sig:
|
|
|
|
Pop(&dummy, (offset) ps);
|
|
|
|
break;
|
|
|
|
case op_lfr:
|
|
|
|
dummy.tk_vn = newvalnum();
|
|
|
|
dummy.tk_size = off_set(lnp);
|
|
|
|
Push(&dummy);
|
|
|
|
break;
|
1988-09-07 09:20:37 +00:00
|
|
|
case op_beq:
|
|
|
|
case op_bge:
|
|
|
|
case op_bgt:
|
|
|
|
case op_bne:
|
|
|
|
case op_ble:
|
|
|
|
case op_blt:
|
|
|
|
Pop(&dummy, (offset) ws);
|
|
|
|
Pop(&dummy, (offset) ws);
|
|
|
|
break;
|
|
|
|
case op_bra:
|
|
|
|
case op_csa:/* ??? */
|
|
|
|
case op_csb:/* ??? */
|
|
|
|
case op_gto:/* ??? */
|
|
|
|
case op_ret:/* ??? */
|
|
|
|
case op_rtt:/* ??? */
|
|
|
|
break;
|
|
|
|
case op_zeq:
|
|
|
|
case op_zge:
|
|
|
|
case op_zgt:
|
|
|
|
case op_zne:
|
|
|
|
case op_zle:
|
|
|
|
case op_zlt:
|
|
|
|
case op_trp:
|
|
|
|
Pop(&dummy, (offset) ws);
|
|
|
|
break;
|
|
|
|
case op_rck:
|
|
|
|
Pop(&dummy, (offset) ps);
|
|
|
|
break;
|
1984-11-26 13:58:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC proc_p find_proc(vn)
|
|
|
|
valnum vn;
|
|
|
|
{
|
|
|
|
/* Find the procedure-identifier with valuenumber vn. */
|
|
|
|
|
|
|
|
entity_p enp;
|
|
|
|
|
|
|
|
enp = find_entity(vn);
|
|
|
|
|
|
|
|
if (enp != (entity_p) 0 && enp->en_kind == ENPROC)
|
|
|
|
return enp->en_pro;
|
|
|
|
|
|
|
|
return (proc_p) 0;
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void side_effects(line_p lnp)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
/* Lnp contains a cai or cal instruction. We try to find the callee
|
|
|
|
* and see what side-effects it has.
|
|
|
|
*/
|
|
|
|
struct token tk;
|
|
|
|
proc_p pp;
|
|
|
|
|
|
|
|
if (INSTR(lnp) == op_cai) {
|
|
|
|
Pop(&tk, (offset) ps);
|
|
|
|
pp = find_proc(tk.tk_vn);
|
|
|
|
} else {
|
|
|
|
assert(INSTR(lnp) == op_cal);
|
|
|
|
pp = PROC(lnp);
|
|
|
|
}
|
|
|
|
if (pp != (proc_p) 0) {
|
|
|
|
kill_call(pp);
|
|
|
|
} else {
|
|
|
|
kill_much();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
STATIC void hopeless(int instr)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
/* The effect of `instr' is too difficult to
|
|
|
|
* compute. We assume worst case behaviour.
|
|
|
|
*/
|
|
|
|
switch (instr) {
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
|
|
|
break;
|
|
|
|
case op_mon:
|
|
|
|
case op_str:
|
1991-10-02 13:03:31 +00:00
|
|
|
case op_nop: /* for volatiles */
|
1984-11-26 13:58:05 +00:00
|
|
|
/* We can't even trust "static" entities. */
|
|
|
|
kill_all();
|
|
|
|
clr_stack();
|
|
|
|
break;
|
|
|
|
case op_blm:
|
|
|
|
case op_bls:
|
|
|
|
case op_sts:
|
|
|
|
kill_much();
|
|
|
|
clr_stack();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-05 21:09:30 +00:00
|
|
|
void vnm(bblock_p bp)
|
1984-11-26 13:58:05 +00:00
|
|
|
{
|
|
|
|
register line_p lnp;
|
|
|
|
register entity_p rep;
|
|
|
|
line_p lfirst;
|
|
|
|
struct token tk, tk1, tk2, tk3;
|
|
|
|
|
|
|
|
for (lnp = bp->b_start; lnp != (line_p) 0; lnp = lnp->l_next) {
|
|
|
|
|
|
|
|
rep = getentity(lnp, &lfirst);
|
|
|
|
switch (instrgroup(lnp)) {
|
|
|
|
case SIMPLE_LOAD:
|
|
|
|
push_entity(rep, lfirst);
|
|
|
|
break;
|
|
|
|
case LOAD_ARRAY:
|
|
|
|
put_aar(bp, lnp, lfirst, rep);
|
|
|
|
/* Fall through ... */
|
|
|
|
case EXPENSIVE_LOAD:
|
|
|
|
push_entity(rep, lfirst);
|
|
|
|
put_expensive_load(bp, lnp, lfirst, rep);
|
|
|
|
break;
|
|
|
|
case STORE_DIRECT:
|
|
|
|
kill_direct(rep);
|
|
|
|
Pop(&tk, rep->en_size);
|
|
|
|
rep->en_vn = tk.tk_vn;
|
|
|
|
break;
|
|
|
|
case STORE_ARRAY:
|
|
|
|
put_aar(bp, lnp, lfirst, rep);
|
|
|
|
/* Fall through ... */
|
|
|
|
case STORE_INDIR:
|
|
|
|
kill_indir(rep);
|
|
|
|
Pop(&tk, rep->en_size);
|
|
|
|
rep->en_vn = tk.tk_vn;
|
|
|
|
break;
|
|
|
|
case UNAIR_OP:
|
|
|
|
Pop(&tk1, op11size(lnp));
|
|
|
|
push_unair_op(bp, lnp, &tk1);
|
|
|
|
break;
|
|
|
|
case BINAIR_OP:
|
|
|
|
Pop(&tk2, op22size(lnp));
|
|
|
|
Pop(&tk1, op12size(lnp));
|
|
|
|
push_binair_op(bp, lnp, &tk1, &tk2);
|
|
|
|
break;
|
|
|
|
case TERNAIR_OP:
|
|
|
|
Pop(&tk3, op33size(lnp));
|
|
|
|
Pop(&tk2, op23size(lnp));
|
|
|
|
Pop(&tk1, op13size(lnp));
|
|
|
|
push_ternair_op(bp, lnp, &tk1, &tk2, &tk3);
|
|
|
|
break;
|
2018-03-05 18:32:06 +00:00
|
|
|
case REMAINDER:
|
|
|
|
Pop(&tk2, op22size(lnp));
|
|
|
|
Pop(&tk1, op12size(lnp));
|
|
|
|
push_remainder(bp, lnp, &tk1, &tk2);
|
|
|
|
break;
|
1984-11-26 13:58:05 +00:00
|
|
|
case KILL_ENTITY:
|
|
|
|
kill_direct(rep);
|
|
|
|
break;
|
|
|
|
case SIDE_EFFECTS:
|
|
|
|
side_effects(lnp);
|
|
|
|
break;
|
|
|
|
case FIDDLE_STACK:
|
|
|
|
fiddle_stack(lnp);
|
|
|
|
break;
|
|
|
|
case IGNORE:
|
|
|
|
break;
|
|
|
|
case HOPELESS:
|
|
|
|
hopeless(INSTR(lnp));
|
|
|
|
break;
|
|
|
|
case BBLOCK_END:
|
1988-09-07 09:20:37 +00:00
|
|
|
fiddle_stack(lnp);
|
1984-11-26 13:58:05 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|