// This file is part of Pike. For copyright information see COPYRIGHT. |
// Pike is distributed under GPL, LGPL and MPL. See the file COPYING |
// for more information. |
|
NOP : |
POP_N_ELEMS (0) : |
POP_N_ELEMS POP_VALUE : POP_N_ELEMS ($1a + 1) |
POP_VALUE POP_VALUE : POP_N_ELEMS (2) |
POP_VALUE POP_N_ELEMS : POP_N_ELEMS ($2a + 1) |
POP_N_ELEMS POP_N_ELEMS : POP_N_ELEMS ($1a + $2a) |
POP_N_ELEMS(1) : POP_VALUE |
POP_VALUE POP_TO_MARK : POP_TO_MARK |
POP_N_ELEMS POP_TO_MARK : POP_TO_MARK |
|
MARK MARK: MARK2 |
MARK POP_MARK: |
MARK2 POP_MARK: MARK |
MARK POP_TO_MARK: |
MARK2 POP_TO_MARK: MARK |
|
SWAP SWAP: |
DUP POP_VALUE: |
DUP POP_N_ELEMS [$2a > 0]: POP_N_ELEMS($2a-1) |
// The opcode list is clearer without this. |
//SYNCH_MARK POP_SYNCH_MARK: |
|
ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a) |
ASSIGN_LOCAL POP_VALUE : ASSIGN_LOCAL_AND_POP($1a) |
RECUR POP_VALUE : RECUR_AND_POP($1a) |
|
// Negation and complement of constants. |
NUMBER(0) : CONST0 |
NUMBER(1) : CONST1 |
NUMBER(-1) : CONST_1 |
NEG_NUMBER(1) : CONST_1 |
NUMBER (0x7fffffff) : BIGNUM |
CONST0 NEGATE : CONST0 |
CONST1 NEGATE : CONST_1 |
CONST_1 NEGATE : CONST1 |
NUMBER NEGATE : NEG_NUMBER($1a) |
NEG_NUMBER NEGATE : NUMBER ($1a) |
NUMBER [ !INT32_NEG_OVERFLOW($1a) && (-$1a) > 0] : NEG_NUMBER (-$1a) |
NEG_NUMBER [ !INT32_NEG_OVERFLOW($1a) && (-$1a) >= 0] : NUMBER (-$1a) |
NEGATE NEGATE : |
COMPL COMPL : |
NEGATE CONST_1 ADD_INTS : COMPL |
NEGATE CONST1 SUBTRACT : COMPL |
NUMBER ASSIGN_LOCAL NEGATE: NUMBER($1a) ASSIGN_LOCAL_AND_POP($2a) NEG_NUMBER($1a) |
NEG_NUMBER ASSIGN_LOCAL NEGATE: NEG_NUMBER($1a) ASSIGN_LOCAL_AND_POP($2a) NUMBER($1a) |
CONST1 ASSIGN_LOCAL NEGATE: CONST1 ASSIGN_LOCAL_AND_POP($2a) CONST_1 |
CONST_1 ASSIGN_LOCAL NEGATE: CONST_1 ASSIGN_LOCAL_AND_POP($2a) CONST1 |
|
CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a) |
CONST0 ASSIGN_LOCAL: CLEAR_LOCAL($2a) CONST0 |
|
LOCAL_2_LOCAL [$1a == $1b] : |
GLOBAL ASSIGN_GLOBAL_AND_POP($1a) : |
|
// Generated by for( int i=0; i<local; i++ ) where i is not used in |
// the loop. |
ASSIGN_LOCAL_NUMBER_AND_POP LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) NUMBER($1b) |
ASSIGN_GLOBAL_NUMBER_AND_POP GLOBAL($1a) : ASSIGN_GLOBAL_NUMBER_AND_POP($1a,$1b) NUMBER($1b) |
NUMBER COMPL: NUMBER(~$1a) |
ASSIGN_LOCAL_NUMBER_AND_POP LOCAL_LVALUE LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) LOCAL_LVALUE($2a) NUMBER($1b) |
ASSIGN_GLOBAL_NUMBER_AND_POP GLOBAL_LVALUE GLOBAL($1a) : ASSIGN_GLOBAL_NUMBER_AND_POP($1a,$1b) GLOBAL_LVALUE($2a) NUMBER($1b) |
ASSIGN_LOCAL_NUMBER_AND_POP GLOBAL_LVALUE LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) GLOBAL_LVALUE($2a) NUMBER($1b) |
|
// Ok, this is ridiculously specific, but it is generated by for(..) |
// when the variable is not used, like above, but for globals: |
ASSIGN_GLOBAL_NUMBER_AND_POP[$1b > -0x80000000L] GLOBAL_LVALUE($1a) DEC: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b - 1) NUMBER($1b - 1) |
|
ASSIGN_GLOBAL_NUMBER_AND_POP[$1b < 0x7fffffff] GLOBAL_LVALUE($1a) INC: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b + 1) NUMBER($1b + 1) |
|
ASSIGN_GLOBAL_NUMBER_AND_POP[$1b > -0x80000000L] GLOBAL_LVALUE($1a) DEC_AND_POP: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b - 1) |
ASSIGN_GLOBAL_NUMBER_AND_POP[$1b < 0x7fffffff] GLOBAL_LVALUE($1a) INC_AND_POP: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b + 1) |
|
LOCAL_LVALUE LOCAL ADD_TO_AND_POP : ADD_LOCALS_AND_POP($1a,$2a) |
LOCAL_LVALUE NUMBER ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,$2a) |
LOCAL_LVALUE CONST_1 ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,-1) |
LOCAL_LVALUE CONST1 ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,1) |
LOCAL_LVALUE CONST0 ADD_TO_AND_POP: |
|
LOCAL_LVALUE LTOSVAL ADD_INT ASSIGN: ADD_LOCAL_INT($1a,$3a) |
LOCAL_LVALUE LTOSVAL ADD_NEG_INT ASSIGN: ADD_LOCAL_INT($1a,-$3a) |
|
NUMBER ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,$1a) |
CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a) |
CONST1 ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,1) |
CONST_1 ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,-1) |
|
NUMBER ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,$1a) |
CONST0 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,0) |
CONST1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,1) |
CONST_1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,-1) |
|
// Remove clearing of locals from the beginning of functions |
// But don't remove clearing of arguments! |
BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) |
BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_2_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) |
BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_4_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) |
|
BYTE ENTRY START_FUNCTION CLEAR_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION |
BYTE ENTRY START_FUNCTION CLEAR_2_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION |
BYTE ENTRY START_FUNCTION CLEAR_4_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION |
|
CLEAR_LOCAL CLEAR_LOCAL($1a) : CLEAR_LOCAL($1a) |
CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) |
CLEAR_2_LOCAL CLEAR_2_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) |
|
// Attempt to make the above trigger more often. |
CLEAR_LOCAL CLEAR_2_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) CLEAR_LOCAL($2a+1) |
CLEAR_LOCAL CLEAR_4_LOCAL($1a+1) : CLEAR_4_LOCAL($1a) CLEAR_LOCAL($2a+3) |
CLEAR_2_LOCAL CLEAR_4_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) CLEAR_2_LOCAL($2a+2) |
|
// Attempt to de-interleave clearing of locals. |
CONST0 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST0 |
CONST1 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST1 |
CONST_1 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST_1 |
NUMBER CLEAR_LOCAL : CLEAR_LOCAL($2a) NUMBER($1a) |
NEG_NUMBER CLEAR_LOCAL : CLEAR_LOCAL($2a) NEG_NUMBER($1a) |
CONSTANT CLEAR_LOCAL : CLEAR_LOCAL($2a) CONSTANT($1a) |
|
|
// CONST_1 MULTIPLY : NEGATE |
// CONST0 MULTIPLY : POP_VALUE CONST0 |
// CONST1 MULTIPLY : |
// NUMBER MULTIPLY [!($1a & ($1a - 1))]: NUMBER(my_log2($1a)) LSH |
|
// CONST_1 DIVIDE : NEGATE |
// CONST1 DIVIDE : |
// NUMBER DIVIDE [!($1a & ($1a - 1))]: NUMBER(my_log2($1a)) RSH |
|
CONST0 SUBTRACT: |
CONST0 XOR: |
CONST_1 XOR: COMPL |
CONST0 RETURN: RETURN_0 |
CONST1 RETURN: RETURN_1 |
CONST0 VOLATILE_RETURN: RETURN_0 |
CONST1 VOLATILE_RETURN: RETURN_1 |
INC POP_VALUE: INC_AND_POP |
POST_INC POP_VALUE: INC_AND_POP |
DEC POP_VALUE: DEC_AND_POP |
POST_DEC POP_VALUE: DEC_AND_POP |
NOT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_ZERO($2a) |
NOT BRANCH_WHEN_ZERO: BRANCH_WHEN_NON_ZERO($2a) |
|
POP_VALUE RETURN_0: RETURN_0 |
POP_N_ELEMS RETURN_0: RETURN_0 |
POP_VALUE RETURN_1: RETURN_1 |
POP_N_ELEMS RETURN_1: RETURN_1 |
|
// F_SYNCH_MARK and F_POP_SYNCH_MARK is output only with -d3 and |
// higher. We keep them solely for balancing the asm debug output. |
#define DeadCodeEndCond(op) \ |
[op != F_LABEL && op != F_SYNCH_MARK && op != F_POP_SYNCH_MARK && op != F_ENTRY] |
BRANCH ? DeadCodeEndCond($2o) : BRANCH($1a) |
RETURN ? DeadCodeEndCond($2o) : RETURN |
VOLATILE_RETURN ? DeadCodeEndCond($2o) : VOLATILE_RETURN |
RETURN_0 ? DeadCodeEndCond($2o) : RETURN_0 |
RETURN_1 ? DeadCodeEndCond($2o) : RETURN_1 |
RETURN_LOCAL ? DeadCodeEndCond($2o) : RETURN_LOCAL($1a) |
|
// Get rid of extra catch-levels. |
// Note that the corresponding exit catch is killed |
// by dead code elimination. |
CATCH ESCAPE_CATCH: |
|
LOCAL_LVALUE INC : INC_LOCAL ($1a) |
LOCAL_LVALUE POST_INC : POST_INC_LOCAL ($1a) |
LOCAL_LVALUE INC_AND_POP : INC_LOCAL_AND_POP ($1a) |
INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a) |
POST_INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a) |
|
LOCAL_LVALUE DEC : DEC_LOCAL ($1a) |
LOCAL_LVALUE POST_DEC : POST_DEC_LOCAL ($1a) |
LOCAL_LVALUE DEC_AND_POP : DEC_LOCAL_AND_POP ($1a) |
DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a) |
POST_DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a) |
|
ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE($1a) INC_AND_POP : ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE($1a) DEC_AND_POP : ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE INC_AND_POP GLOBAL($1a) : GLOBAL_LVALUE($1a) INC |
GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a) : GLOBAL_LVALUE($1a) DEC |
|
ASSIGN_LOCAL RETURN [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)]: RETURN |
ASSIGN_LOCAL VOLATILE_RETURN [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)]: VOLATILE_RETURN |
|
ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) RETURN LABEL($2a): ASSIGN_LOCAL($1a) RETURN_IF_TRUE LABEL($2a) |
ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) VOLATILE_RETURN LABEL($2a): ASSIGN_LOCAL($1a) RETURN_IF_TRUE LABEL($2a) |
|
ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) RETURN LABEL($2a) [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)] : RETURN_IF_TRUE ASSIGN_LOCAL($1a) LABEL($2a) |
ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) VOLATILE_RETURN LABEL($2a) [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)] : RETURN_IF_TRUE ASSIGN_LOCAL($1a) LABEL($2a) |
|
ASSIGN_GLOBAL BRANCH_WHEN_ZERO GLOBAL($1a) RETURN LABEL($2a): ASSIGN_GLOBAL($1a) RETURN_IF_TRUE LABEL($2a) |
ASSIGN_GLOBAL BRANCH_WHEN_ZERO GLOBAL($1a) VOLATILE_RETURN LABEL($2a): ASSIGN_GLOBAL($1a) RETURN_IF_TRUE LABEL($2a) |
|
|
GLOBAL_LVALUE INC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) INC |
GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) DEC |
|
CONST1 BRANCH_WHEN_ZERO: |
CONST0 BRANCH_WHEN_ZERO: BRANCH($2a) |
CONST1 BRANCH_WHEN_NON_ZERO: BRANCH($2a) |
CONST0 BRANCH_WHEN_NON_ZERO: |
NUMBER [$1a] BRANCH_WHEN_ZERO: |
NUMBER [$1a] BRANCH_WHEN_NON_ZERO: BRANCH($2a) |
|
// These optimizations are now handled in optimize_eq |
// CONST0 BRANCH_WHEN_EQ: BRANCH_WHEN_ZERO($2a) |
// CONST0 BRANCH_WHEN_NE: BRANCH_WHEN_NON_ZERO($2a) |
// |
// This one is not safe. |
// CONST0 EQ: NOT |
|
EQ BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_EQ ($2a) |
NE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_NE ($2a) |
LT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LT ($2a) |
GT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GT ($2a) |
LE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LE ($2a) |
GE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GE ($2a) |
|
EQ BRANCH_WHEN_ZERO: BRANCH_WHEN_NE ($2a) |
NE BRANCH_WHEN_ZERO: BRANCH_WHEN_EQ ($2a) |
// The following only work on total orders. We can't assume that. |
// LT BRANCH_WHEN_ZERO: BRANCH_WHEN_GE ($2a) |
// GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a) |
// LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a) |
// GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a) |
|
EQ LOR: EQ_OR ($2a) |
EQ LAND: EQ_AND ($2a) |
|
EQ NOT: NE |
NE NOT: EQ |
|
// The following only work on total orders. We can't assume that. |
// |
// LT NOT: GE |
// GT NOT: LE |
// LE NOT: GT |
// GE NOT: LT |
|
LOCAL LOCAL : 2_LOCALS ($1a,$2a) |
MARK LOCAL : MARK_AND_LOCAL ($2a) |
MARK GLOBAL: MARK_AND_GLOBAL ($2a) |
MARK STRING : MARK_AND_STRING($2a) |
MARK EXTERNAL : MARK_AND_EXTERNAL($2a,$2b) |
MARK CONST0 : MARK_AND_CONST0 |
MARK CONST1 : MARK_AND_CONST1 |
LOCAL SIZEOF: SIZEOF_LOCAL ($1a) |
MARK_AND_LOCAL SIZEOF: MARK SIZEOF_LOCAL ($1a) |
2_LOCALS SIZEOF: LOCAL($1a) SIZEOF_LOCAL ($1b) |
STRING INDEX: STRING_INDEX ($1a) |
INDEX SWITCH: SWITCH_ON_INDEX($2a) |
LOCAL SWITCH: SWITCH_ON_LOCAL($1a,$2a) |
2_LOCALS SWITCH: LOCAL($1a) SWITCH_ON_LOCAL($1b,$2a) |
|
STRING CLEAR_STRING_SUBTYPE: STRING ($1a) |
CONST0 CLEAR_STRING_SUBTYPE: CONST0 |
CONST1 CLEAR_STRING_SUBTYPE: CONST1 |
CONST_1 CLEAR_STRING_SUBTYPE: CONST_1 |
NUMBER CLEAR_STRING_SUBTYPE: NUMBER($1a) |
NEG_NUMBER CLEAR_STRING_SUBTYPE: NEG_NUMBER($1a) |
|
LOCAL INDEX: LOCAL_INDEX ($1a) |
LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_INDEX ($1a) |
MARK_AND_LOCAL INDEX: MARK LOCAL_INDEX ($1a) |
MARK_AND_LOCAL CLEAR_STRING_SUBTYPE INDEX: MARK LOCAL_INDEX ($1a) |
2_LOCALS INDEX: LOCAL_LOCAL_INDEX($1b,$1a) |
2_LOCALS CLEAR_STRING_SUBTYPE INDEX: LOCAL_LOCAL_INDEX($1b,$1a) |
|
2_LOCALS [$1a == $1b]: LOCAL($1a) DUP |
GLOBAL GLOBAL($1a): GLOBAL($1a) DUP |
|
CONST0 INDEX: POS_INT_INDEX (0) |
CONST_1 INDEX: NEG_INT_INDEX (1) |
CONST1 INDEX: POS_INT_INDEX (1) |
NUMBER INDEX: POS_INT_INDEX ($1a) |
NEG_NUMBER INDEX: NEG_INT_INDEX ($1a) |
POS_INT_INDEX [$1a < 0 && !INT32_NEG_OVERFLOW($1a) ]: NEG_INT_INDEX (-$1a) |
NEG_INT_INDEX [-$1a >= 0]: POS_INT_INDEX (-$1a) |
|
BRANCH_WHEN_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_NON_ZERO($2a) LABEL($1a) |
BRANCH_WHEN_NON_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_ZERO($2a) LABEL($1a) |
|
BRANCH_WHEN_EQ BRANCH LABEL ($1a) : BRANCH_WHEN_NE($2a) LABEL($1a) |
BRANCH_WHEN_NE BRANCH LABEL ($1a) : BRANCH_WHEN_EQ($2a) LABEL($1a) |
|
// The following only work on total orders. We can't assume that. |
// |
// BRANCH_WHEN_LT BRANCH LABEL ($1a) : BRANCH_WHEN_GE($2a) LABEL($1a) |
// BRANCH_WHEN_GE BRANCH LABEL ($1a) : BRANCH_WHEN_LT($2a) LABEL($1a) |
// |
// BRANCH_WHEN_LE BRANCH LABEL ($1a) : BRANCH_WHEN_GT($2a) LABEL($1a) |
// BRANCH_WHEN_GT BRANCH LABEL ($1a) : BRANCH_WHEN_LE($2a) LABEL($1a) |
|
|
CONST0 ADD_INTS: ADD_INT (0) |
CONST1 ADD_INTS: ADD_INT (1) |
CONST_1 ADD_INTS: ADD_NEG_INT (1) |
NUMBER [$1a >= 0] ADD_INTS : ADD_INT ($1a) |
NEG_NUMBER [$1a > 0] ADD_INTS : ADD_NEG_INT ($1a) |
|
CONST0 ADD: ADD_INT (0) |
CONST1 ADD: ADD_INT (1) |
CONST_1 ADD: ADD_NEG_INT (1) |
NUMBER [$1a >= 0] ADD : ADD_INT ($1a) |
NEG_NUMBER [$1a > 0] ADD : ADD_NEG_INT ($1a) |
|
CONST1 SUBTRACT: ADD_NEG_INT (1) |
CONST_1 SUBTRACT: ADD_INT (1) |
NUMBER [$1a >= 0] SUBTRACT : ADD_NEG_INT ($1a) |
NEG_NUMBER [$1a > 0] SUBTRACT : ADD_INT ($1a) |
|
// This set of optimizations is broken. Consider the case: |
// STRING ADD_INT ADD_INT |
// |
// ADD_INT ADD_INT: ADD_INT ($1a+$2a) |
// ADD_NEG_INT ADD_NEG_INT: ADD_NEG_INT ($1a+$2a) |
// ADD_NEG_INT ADD_INT [$1a <= $2a]: ADD_INT ($2a-$1a) |
// ADD_NEG_INT ADD_INT [$1a > $2a]: ADD_NEG_INT ($1a-$2a) |
// ADD_INT ADD_NEG_INT [$2a <= $1a]: ADD_INT ($1a-$2a) |
// ADD_INT ADD_NEG_INT [$2a > $1a]: ADD_NEG_INT ($2a-$1a) |
|
// FIXME: BIGNUMS? |
// |
// NUMBER ADD_INT : NUMBER ($1a+$2a) |
// NUMBER ADD_NEG_INT : NUMBER ($1a-$2a) |
// CONST1 ADD_INT : NUMBER(1+$2a) |
// CONST1 ADD_NEG_INT : NUMBER(1-$2a) |
// CONST_1 ADD_INT : NUMBER($2a-1) |
// CONST_1 ADD_NEG_INT : NUMBER(-(1+$2a)) |
|
// FIXME: What about LTOSVAL_AND_FREE variants of the following three rules? |
|
LTOSVAL2_AND_FREE ADD ASSIGN : ADD_TO |
LTOSVAL ADD ASSIGN : ADD_TO |
|
LTOSVAL2_AND_FREE ADD_INTS ASSIGN : ADD_TO |
LTOSVAL ADD_INTS ASSIGN : ADD_TO |
|
LTOSVAL2_AND_FREE ADD_FLOATS ASSIGN : ADD_TO |
LTOSVAL ADD_FLOATS ASSIGN : ADD_TO |
|
LOCAL CONST1 ADD_TO : INC_LOCAL($1a) |
LOCAL CONST_1 ADD_TO : DEC_LOCAL($1a) |
|
ADD_TO POP_VALUE : ADD_TO_AND_POP |
ASSIGN POP_VALUE : ASSIGN_AND_POP |
|
LOCAL CONST1 ADD_TO_AND_POP : INC_LOCAL_AND_POP($1a) |
LOCAL CONST_1 ADD_TO_AND_POP : DEC_LOCAL_AND_POP($1a) |
|
INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP($1a) |
DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP($1a) |
|
#ifdef EAT_STACK |
APPLY ASSIGN_LOCAL_AND_POP : APPLY_ASSIGN_LOCAL_AND_POP($1a,$2a) |
#endif |
ASSIGN_LOCAL_AND_POP INC_LOCAL($1a) : ADD_INT(1) ASSIGN_LOCAL($1a) |
ASSIGN_LOCAL_AND_POP DEC_LOCAL($1a) : ADD_NEG_INT(1) ASSIGN_LOCAL($1a) |
|
LOCAL RETURN : RETURN_LOCAL($1a) |
LOCAL VOLATILE_RETURN : RETURN_LOCAL($1a) |
|
NUMBER ADD_INT [ !INT32_ADD_OVERFLOW($1a, $2a) ] : NUMBER($1a+$2a) |
NUMBER ADD_NEG_INT [ !INT32_SUB_OVERFLOW($1a, $2a) ]: NUMBER($1a-$2a) |
NEG_NUMBER ADD_INT [ !INT32_SUB_OVERFLOW($2a, $1a) ]: NUMBER($2a-$1a) |
NEG_NUMBER ADD_NEG_INT [ !INT32_NEG_OVERFLOW($1a) && !INT32_SUB_OVERFLOW(-$1a, $2a) ]: NUMBER(-$1a-$2a) |
|
CONST0 ADD_INT : NUMBER($2a) |
CONST0 ADD_NEG_INT : NEG_NUMBER($2a) |
CONST1 ADD_INT [($2a+1) > 0] : NUMBER($2a+1) |
CONST1 ADD_NEG_INT [ !INT32_SUB_OVERFLOW($2a, 1) ] : NEG_NUMBER($2a-1) |
CONST_1 ADD_INT [ !INT32_SUB_OVERFLOW($2a, 1) ] : NUMBER($2a-1) |
CONST_1 ADD_NEG_INT [ !INT32_ADD_OVERFLOW($2a, 1) && ($2a+1) > 0] : NEG_NUMBER($2a+1) |
CONST0 LOCAL ADD_INTS : LOCAL($2a) |
CONST0 LOCAL NEGATE ADD_INTS : LOCAL($2a) NEGATE |
CONST0 GLOBAL ADD_INTS : GLOBAL($2a) |
CONST0 GLOBAL NEGATE ADD_INTS : GLOBAL($2a) NEGATE |
|
LOCAL ADD_INT LOCAL($1a) : LOCAL($1a) DUP ADD_INT($2a) SWAP |
GLOBAL ADD_INT GLOBAL($1a) : GLOBAL($1a) DUP ADD_INT($2a) SWAP |
LOCAL ADD_NEG_INT LOCAL($1a) : LOCAL($1a) DUP ADD_NEG_INT($2a) SWAP |
GLOBAL ADD_NEG_INT GLOBAL($1a) : GLOBAL($1a) DUP ADD_NEG_INT($2a) SWAP |
|
LOCAL BRANCH_WHEN_NON_ZERO : BRANCH_IF_LOCAL($1a) POINTER($2a) |
LOCAL BRANCH_WHEN_ZERO : BRANCH_IF_NOT_LOCAL($1a) POINTER($2a) |
|
// quick_branch_when[_non]_zero _knows_ that the |
// value on the stack is an integer. |
GT BRANCH_WHEN_ZERO : GT QUICK_BRANCH_WHEN_ZERO($2a) |
GE BRANCH_WHEN_ZERO : GE QUICK_BRANCH_WHEN_ZERO($2a) |
LT BRANCH_WHEN_ZERO : LT QUICK_BRANCH_WHEN_ZERO($2a) |
LE BRANCH_WHEN_ZERO : LE QUICK_BRANCH_WHEN_ZERO($2a) |
|
GT BRANCH_WHEN_NON_ZERO : GT QUICK_BRANCH_WHEN_NON_ZERO($2a) |
GE BRANCH_WHEN_NON_ZERO : GE QUICK_BRANCH_WHEN_NON_ZERO($2a) |
LT BRANCH_WHEN_NON_ZERO : LT QUICK_BRANCH_WHEN_NON_ZERO($2a) |
LE BRANCH_WHEN_NON_ZERO : LE QUICK_BRANCH_WHEN_NON_ZERO($2a) |
|
// It is not really neccessary to set up a frame for these cases. |
// Deluxe version: Also avoid the argument/local clearing, asm-level |
// register pushing etc. |
// |
// These are functions returning a constant, and doing nothing else. |
MARK_AT(0) POP_TO_MARK INIT_FRAME RETURN_0 : RETURN_0 |
MARK_AT(0) POP_TO_MARK INIT_FRAME UNDEFINED RETURN : UNDEFINED RETURN |
MARK_AT(0) POP_TO_MARK INIT_FRAME RETURN_1 : RETURN_1 |
MARK_AT(0) POP_TO_MARK INIT_FRAME NUMBER RETURN : NUMBER($4a) RETURN |
MARK_AT(0) POP_TO_MARK INIT_FRAME STRING RETURN : STRING($4a) RETURN |
MARK_AT(0) POP_TO_MARK INIT_FRAME CONSTANT RETURN : CONSTANT($4a) RETURN |
MARK_AT(0) POP_TO_MARK INIT_FRAME NEG_NUMBER RETURN : NEG_NUMBER($4a) RETURN |
|
// Branches that jump to the next instruction |
// Basic branches |
BRANCH LABEL($1a) : LABEL($1a) |
BRANCH_WHEN_ZERO LABEL($1a) : POP_VALUE LABEL($1a) |
BRANCH_WHEN_NON_ZERO LABEL($1a) : POP_VALUE LABEL($1a) |
BRANCH_WHEN_EQ LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
BRANCH_WHEN_NE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
BRANCH_WHEN_LT LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
BRANCH_WHEN_LE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
BRANCH_WHEN_GT LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
BRANCH_WHEN_GE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) |
// These variants use a POINTER |
BRANCH_IF_NOT_LOCAL_ARROW POINTER LABEL ($2a) : LABEL($2a) |
BRANCH_IF_LOCAL POINTER LABEL($2a) : LABEL($2a) |
BRANCH_IF_NOT_LOCAL POINTER LABEL($2a) : LABEL($2a) |
|
#define OPT_INCDEC(X) \ |
X##_LOCAL_AND_POP LOCAL ($1a) : X##_LOCAL ($1a) ; \ |
X##_LOCAL_AND_POP LOCAL LOCAL ($1a) : LOCAL($2a) X##_LOCAL ($1a) ; \ |
X##_LOCAL_AND_POP GLOBAL LOCAL ($1a) : GLOBAL($2a) X##_LOCAL ($1a) ; |
|
OPT_INCDEC(INC) |
OPT_INCDEC(DEC) |
|
ASSIGN_LOCAL_AND_POP LOCAL($1a) : ASSIGN_LOCAL($1a) |
ASSIGN_GLOBAL_AND_POP GLOBAL($1a) : ASSIGN_GLOBAL($1a) |
CLEAR_LOCAL LOCAL($1a) : CLEAR_LOCAL($1a) CONST0 |
#ifdef EAT_STACK |
APPLY_ASSIGN_LOCAL_AND_POP LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b) |
#endif |
|
DEC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : DEC_LOCAL ($1a) MARK_X(1) |
INC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : INC_LOCAL ($1a) MARK_X(1) |
ASSIGN_GLOBAL_AND_POP MARK GLOBAL($1a) : ASSIGN_GLOBAL($1a) MARK_X(1) |
ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL($1a) : ASSIGN_LOCAL($1a) MARK_X(1) |
ASSIGN_LOCAL_AND_POP NUMBER LOCAL($1a) : ASSIGN_LOCAL($1a) NUMBER($2a) SWAP |
ASSIGN_LOCAL_AND_POP STRING LOCAL($1a) : ASSIGN_LOCAL($1a) STRING($2a) SWAP |
ASSIGN_LOCAL_AND_POP MARK_AND_STRING LOCAL($1a) : ASSIGN_LOCAL($1a) STRING($2a) SWAP MARK_X(2) |
|
#ifdef EAT_STACK |
APPLY_ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b) MARK_X(1) |
#endif |
|
ASSIGN_LOCAL ASSIGN_LOCAL($1a) : ASSIGN_LOCAL($1a) |
|
#if 0 |
// The following set of rules attempt to push the mark toward the apply. |
// The idea is to push it the entire way, to be able to have an apply |
// opcode that contains the stack depth, and thus doesn't need the mark |
// stack. |
|
// MARK rules |
MARK LOCAL : LOCAL($2a) MARK_X(1) |
MARK STRING : STRING($2a) MARK_X(1) |
MARK NUMBER : NUMBER($2a) MARK_X(1) |
MARK CONST0 : CONST0 MARK_X(1) |
MARK CONST1 : CONST1 MARK_X(1) |
MARK CONST_1 : CONST_1 MARK_X(1) |
MARK NEG_NUMBER : NEG_NUMBER($2a) MARK_X(1) |
MARK GLOBAL : GLOBAL($2a) MARK_X(1) |
MARK MARK_APPLY : MARK_APPLY($2a) MARK_X(1) |
MARK CONSTANT : CONSTANT($2a) MARK_X(1) |
//MARK FLOAT : FLOAT($2a) MARK_X(1) |
MARK LFUN : LFUN($2a) MARK_X(1) |
MARK LTOSVAL : LTOSVAL MARK_X(1) |
MARK LOCAL_LVALUE : LOCAL_LVALUE($2a) MARK_X(2) |
MARK 2_LOCALS : 2_LOCALS($2a,$2b) MARK_X(2) |
MARK NEGATE : NEGATE MARK |
|
// MARK_X rules |
MARK_X(0) : MARK |
MARK_X LOCAL : LOCAL($2a) MARK_X($1a+1) |
MARK_X STRING : STRING($2a) MARK_X($1a+1) |
MARK_X NUMBER : NUMBER($2a) MARK_X($1a+1) |
MARK_X CONST0 : CONST0 MARK_X($1a+1) |
MARK_X CONST1 : CONST1 MARK_X($1a+1) |
MARK_X CONST_1 : CONST_1 MARK_X($1a+1) |
MARK_X NEG_NUMBER : NEG_NUMBER($2a) MARK_X($1a+1) |
MARK_X GLOBAL : GLOBAL($2a) MARK_X($1a+1) |
MARK_X MARK_APPLY : MARK_APPLY($2a) MARK_X($1a+1) |
MARK_X CONSTANT : CONSTANT($2a) MARK_X($1a+1) |
//MARK_X FLOAT : FLOAT($2a) MARK_X($1a+1) |
MARK_X LFUN : LFUN($2a) MARK_X($1a+1) |
MARK_X LTOSVAL : LTOSVAL MARK_X($1a+1) |
MARK_X LOCAL_LVALUE : LOCAL_LVALUE($2a) MARK_X($1a+2) |
MARK_X 2_LOCALS : 2_LOCALS($2a,$2b) MARK_X($1a+2) |
MARK_X NEGATE : NEGATE MARK_X($1a) |
|
#else /* !0 */ |
|
// MARK_X rules |
MARK_X(0) : MARK |
LOCAL MARK_X [$2a>0] : MARK_X($2a-1) LOCAL($1a) |
STRING MARK_X [$2a>0] : MARK_X($2a-1) STRING($1a) |
NUMBER MARK_X [$2a>0] : MARK_X($2a-1) NUMBER($1a) |
CONST0 MARK_X [$2a>0] : MARK_X($2a-1) CONST0 |
CONST1 MARK_X [$2a>0] : MARK_X($2a-1) CONST1 |
CONST_1 MARK_X [$2a>0] : MARK_X($2a-1) CONST_1 |
NEG_NUMBER MARK_X [$2a>0] : MARK_X($2a-1) NEG_NUMBER($1a) |
GLOBAL MARK_X [$2a>0] : MARK_X($2a-1) GLOBAL($1a) |
MARK_APPLY MARK_X [$2a>0] : MARK_X($2a-1) MARK_APPLY($1a) |
CONSTANT MARK_X [$2a>0] : MARK_X($2a-1) CONSTANT($1a) |
//FLOAT MARK_X [$2a>0] : MARK_X($2a-1) FLOAT($1a) |
LFUN MARK_X [$2a>0] : MARK_X($2a-1) LFUN($1a) |
LTOSVAL MARK_X [$2a>0] : MARK_X($2a-1) LTOSVAL |
LOCAL_LVALUE MARK_X [$2a>1] : MARK_X($2a-2) LOCAL_LVALUE($1a) |
2_LOCALS MARK_X [$2a>0] : LOCAL($1a) MARK_X($2a-1) LOCAL($1b) |
SWAP MARK_X : MARK_X($2a) SWAP |
DUP MARK_X [$2a>0] : MARK_X($2a-1) DUP |
|
CONST_1 ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) CONST_1 ASSIGN_LOCAL($2a) |
CONST1 ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) CONST1 ASSIGN_LOCAL($2a) |
NUMBER ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) NUMBER($1a) ASSIGN_LOCAL($2a) |
NEG_NUMBER ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) NEG_NUMBER($1a) ASSIGN_LOCAL($2a) |
|
#endif /* 0 */ |
|
MARK_X [$1a>0] POP_VALUE : POP_VALUE MARK_X($1a-1) |
MARK_X POP_N_ELEMS [$1a >= $2a] : POP_N_ELEMS($2a) MARK_X($1a-$2a) |
|
#define BasicBranch2(Branch,Oper,Pre,Post,Variable) \ |
Variable Branch Pre Variable ($1a) : Variable ($1a) Oper ($2a) Post ; \ |
ASSIGN_##Variable Branch Pre Variable ($1a) : ASSIGN_##Variable($1a) Oper ($2a) Post ; |
|
#define BasicBranch1(Branch,Oper,Pre,Post) \ |
BasicBranch2(Branch,Oper,Pre,Post,LOCAL) \ |
BasicBranch2(Branch,Oper,Pre,Post,GLOBAL) |
|
#define BasicBranch0(Branch,Oper) \ |
BasicBranch1(Branch,Oper,MARK,MARK_X(1)) \ |
BasicBranch1(Branch,Oper, , ) |
|
BasicBranch0(BRANCH_WHEN_NON_ZERO, BRANCH_AND_POP_WHEN_NON_ZERO) |
BasicBranch0(BRANCH_WHEN_ZERO, BRANCH_AND_POP_WHEN_ZERO) |
|
#define SimpleBranch(Sequence,X) \ |
Sequence BRANCH_WHEN_ZERO Sequence : Sequence BRANCH_AND_POP_WHEN_ZERO ( X ) ; \ |
Sequence BRANCH_WHEN_ZERO MARK Sequence : Sequence BRANCH_AND_POP_WHEN_ZERO ( X ) MARK_X(1) ; |
|
SimpleBranch( LOCAL_ARROW($1a, $1b), $2a ) |
SimpleBranch( LOCAL_ARROW($1a, $1b) ARROW($2a), $3a ) |
SimpleBranch( LOCAL_ARROW($1a, $1b) ARROW($2a) ARROW($3a), $4a ) |
SimpleBranch( LOCAL_ARROW($1a, $1b) ARROW($2a) ARROW($3a) ARROW($4a), $5a ) |
SimpleBranch( GLOBAL_LOCAL_INDEX($1a, $1b) , $2a ) |
SimpleBranch( LOCAL_LOCAL_INDEX($1a, $1b) , $2a ) |
|
SimpleBranch( GLOBAL($1a) ARROW ($2a), $3a ) |
|
LOCAL ASSIGN_LOCAL_AND_POP : LOCAL_2_LOCAL($2a,$1a) |
GLOBAL ASSIGN_LOCAL_AND_POP : GLOBAL_2_LOCAL($1a,$2a) |
LOCAL ASSIGN_GLOBAL_AND_POP : LOCAL_2_GLOBAL($2a,$1a) |
|
LOCAL ARROW : LOCAL_ARROW($2a,$1a) |
LOCAL_ARROW BRANCH_WHEN_ZERO: BRANCH_IF_NOT_LOCAL_ARROW($1a,$1b) POINTER($2a) |
|
GLOBAL LOCAL_INDEX : GLOBAL_LOCAL_INDEX($1a,$2a) |
|
SIZEOF CONST1 BRANCH_WHEN_LT : SIZEOF BRANCH_WHEN_ZERO ($3a) |
SIZEOF_LOCAL CONST1 BRANCH_WHEN_LT : SIZEOF_LOCAL($1a) BRANCH_WHEN_ZERO ($3a) |
SIZEOF CONST0 BRANCH_WHEN_LE : SIZEOF BRANCH_WHEN_ZERO ($3a) |
SIZEOF_LOCAL CONST0 BRANCH_WHEN_LE : SIZEOF_LOCAL($1a) BRANCH_WHEN_ZERO ($3a) |
|
CLEAR_LOCAL DEC_LOCAL_AND_POP($1a) : CONST_1 ASSIGN_LOCAL_AND_POP($1a) |
CLEAR_LOCAL INC_LOCAL_AND_POP($1a) : CONST1 ASSIGN_LOCAL_AND_POP($1a) |
|
NUMBER POP_VALUE : |
STRING POP_VALUE : |
//FLOAT POP_VALUE : |
CONSTANT POP_VALUE : |
LOCAL POP_VALUE : |
IDENTIFIER POP_VALUE : |
TRAMPOLINE POP_VALUE : |
|
RECUR RETURN [check_tailrecursion()] : TAIL_RECUR ($1a) |
|
// This doesn't really work |
// MARK TAIL_RECUR : BRANCH ($1a) |
|
ASSIGN_LOCAL BRANCH_WHEN_ZERO 2_LOCALS(,$1a) BRANCH_WHEN_EQ : ASSIGN_LOCAL($1a) BRANCH_AND_POP_WHEN_ZERO($2a) LOCAL($3a) BRANCH_WHEN_EQ($4a) |
ASSIGN_LOCAL BRANCH_WHEN_ZERO 2_LOCALS(,$1a) BRANCH_WHEN_NE : ASSIGN_LOCAL($1a) BRANCH_AND_POP_WHEN_ZERO($2a) LOCAL($3a) BRANCH_WHEN_NE($4a) |
|
/* This will facilitate other optimizations I hope */ |
CLEAR_LOCAL MARK LOCAL [ $1a != $3a ] : MARK LOCAL($3a) CLEAR_LOCAL($1a) |
|
/* The result of this optimization could be reordered... */ |
CLEAR_LOCAL MARK LOCAL($1a) : MARK CLEAR_LOCAL($1a) CONST0 |
|
|
|
#define LOW_MKCALLOPTS(A) \ |
A POP_VALUE: A##_AND_POP($1a); \ |
A [ check_tailrecursion() ] RETURN : A##_AND_RETURN($1a) ; \ |
A##_AND_RETURN ? DeadCodeEndCond($2o) : A##_AND_RETURN($1a) ; |
|
#define MKCALLOPTS(A) \ |
MARK A: MARK_##A($2a) ; \ |
LOW_MKCALLOPTS(A); \ |
LOW_MKCALLOPTS(MARK_##A); |
|
|
MKCALLOPTS(APPLY) |
MKCALLOPTS(CALL_LFUN) |
MKCALLOPTS(CALL_BUILTIN) |
// MARK CALL_FUNCTION doesn't make any sense... |
LOW_MKCALLOPTS(CALL_FUNCTION) |
|
// MARK CALL_OTHER doesn't make any sense either... |
LOW_MKCALLOPTS(CALL_OTHER) |
|
CALL_BUILTIN1 POP_VALUE : CALL_BUILTIN1_AND_POP ($1a) |
|
LTOSVAL_CALL_BUILTIN_AND_ASSIGN POP_VALUE : LTOSVAL_CALL_BUILTIN_AND_ASSIGN_POP($1a) |
|
#define OPT_TYPEP(X,Y) \ |
CALL_BUILTIN1 [ Pike_compiler->new_program->constants[$1a].sval.u.efun->function == X ] BRANCH_WHEN_ZERO : BRANCH_IF_TYPE_IS_NOT(Y) POINTER($2a); |
|
#if 1 |
OPT_TYPEP(f_intp, T_INT) |
OPT_TYPEP(f_stringp, T_STRING) |
OPT_TYPEP(f_arrayp, T_ARRAY) |
OPT_TYPEP(f_floatp, T_FLOAT) |
OPT_TYPEP(f_mappingp, T_MAPPING) |
OPT_TYPEP(f_multisetp, T_MULTISET) |
#endif |
|
// Move lvalues up on the stack. |
#define MOVE_LVAL(L_G1, L_G2) \ |
NUMBER ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) NUMBER($1a) ASSIGN_##L_G1##_AND_POP($2a); \ |
NEG_NUMBER ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) NEG_NUMBER($1a) ASSIGN_##L_G1##_AND_POP($2a); \ |
CONST1 ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) CONST1 ASSIGN_##L_G1##_AND_POP($2a); \ |
CONST_1 ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) CONST_1 ASSIGN_##L_G1##_AND_POP($2a); |
|
MOVE_LVAL(LOCAL,LOCAL) |
MOVE_LVAL(GLOBAL,LOCAL) |
MOVE_LVAL(LOCAL,GLOBAL) |
MOVE_LVAL(GLOBAL,GLOBAL) |
|
CLEAR_LOCAL LOCAL_LVALUE: LOCAL_LVALUE($2a) CLEAR_LOCAL($1a) |
CLEAR_LOCAL GLOBAL_LVALUE: GLOBAL_LVALUE($2a) CLEAR_LOCAL($1a) |
CONST0 ASSIGN_GLOBAL_AND_POP LOCAL_LVALUE: LOCAL_LVALUE($3a) CONST0 ASSIGN_GLOBAL_AND_POP($2a) |
CONST0 ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE: GLOBAL_LVALUE($3a) CONST0 ASSIGN_GLOBAL_AND_POP($2a) |
|
GLOBAL_LVALUE CONST0 ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : CONST1 ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE CONST0 ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : CONST_1 ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE CONST_1 ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : CONST0 ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE CONST1 ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : CONST0 ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE NUMBER ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : NUMBER($2a) ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE NUMBER ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : NUMBER($2a) ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE NEG_NUMBER ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : NEG_NUMBER($2a) ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
GLOBAL_LVALUE NEG_NUMBER ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : NEG_NUMBER($2a) ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) |
|
// Move marks to where they're relevant. |
MARK CLEAR_LOCAL: CLEAR_LOCAL($2a) MARK |
MARK NUMBER ASSIGN_LOCAL_AND_POP: NUMBER($2a) ASSIGN_LOCAL_AND_POP($3a) MARK |
MARK NUMBER ASSIGN_GLOBAL_AND_POP: NUMBER($2a) ASSIGN_GLOBAL_AND_POP($3a) MARK |
MARK NEG_NUMBER ASSIGN_LOCAL_AND_POP: NEG_NUMBER($2a) ASSIGN_LOCAL_AND_POP($3a) MARK |
MARK NEG_NUMBER ASSIGN_GLOBAL_AND_POP: NEG_NUMBER($2a) ASSIGN_GLOBAL_AND_POP($3a) MARK |
MARK_AND_CONST1 ASSIGN_LOCAL_AND_POP: CONST1 ASSIGN_LOCAL_AND_POP($3a) MARK |
MARK_AND_CONST1 ASSIGN_GLOBAL_AND_POP: CONST1 ASSIGN_GLOBAL_AND_POP($3a) MARK |
MARK CONST_1 ASSIGN_LOCAL_AND_POP: CONST_1 ASSIGN_LOCAL_AND_POP($3a) MARK |
MARK CONST_1 ASSIGN_GLOBAL_AND_POP: CONST_1 ASSIGN_GLOBAL_AND_POP($3a) MARK |
|
CONST_1 COMPL : CONST0 |
CONST_1 ASSIGN_LOCAL COMPL : CONST_1 ASSIGN_LOCAL_AND_POP($2a) CONST0 |
CONST_1 ASSIGN_GLOBAL COMPL : CONST_1 ASSIGN_GLOBAL_AND_POP($2a) CONST0 |
|
CONST0 COMPL : CONST_1 |
CONST0 ASSIGN_LOCAL COMPL : CLEAR_LOCAL($2a) CONST_1 |
CONST0 ASSIGN_GLOBAL COMPL : CONST0 ASSIGN_GLOBAL_AND_POP($2a) CONST_1 |
|