void WordcodeEmitter::emitPushuint(const uint8_t *pc) { // FIXME: wrong for 64-bit, we want 32 bits of payload pc++; uint32_t value = pool->cpool_uint[AvmCore::readU30(pc)]; if ((value & 0xF0000000U) == 0) { CHECK(2); *dest++ = NEW_OPCODE(WOP_pushbits); *dest++ = (value << 3) | kIntegerType; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(WOP_pushbits, dest-2); #endif } else { union { double d; uint32_t bits[2]; } v; v.d = (double)value; CHECK(3); *dest++ = NEW_OPCODE(WOP_push_doublebits); *dest++ = v.bits[0]; *dest++ = v.bits[1]; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(WOP_push_doublebits, dest-3); #endif } }
void ST_avmplus_peephole::test0() { #ifdef AVMPLUS_DIRECT_THREADED WordcodeEmitter* t = new WordcodeEmitter(core, NULL, opcode_labels); #else WordcodeEmitter* t = new WordcodeEmitter(core, NULL); #endif t->emitOp1(WOP_getlocal, 5); t->emitOp1(WOP_getlocal, 4); t->emitOp1(WOP_getlocal, 65536); t->emitOp1(WOP_getlocal, 7); t->emitOp1(WOP_getlocal, 6); uint32_t* code; uint32_t len = t->epilogue(&code); verifyPass(len == 6, "len == 6", __FILE__, __LINE__); verifyPass(code[0] == NEW_OPCODE(WOP_get2locals), "code[0] == NEW_OPCODE(WOP_get2locals)", __FILE__, __LINE__); verifyPass(code[1] == ((4 << 16) | 5), "code[1] == ((4 << 16) | 5)", __FILE__, __LINE__); verifyPass(code[2] == NEW_OPCODE(WOP_getlocal), "code[2] == NEW_OPCODE(WOP_getlocal)", __FILE__, __LINE__); verifyPass(code[3] == 65536, "code[3] == 65536", __FILE__, __LINE__); verifyPass(code[4] == NEW_OPCODE(WOP_get2locals), "code[4] == NEW_OPCODE(WOP_get2locals)", __FILE__, __LINE__); verifyPass(code[5] == ((6 << 16) | 7), "code[5] == ((6 << 16) | 7)", __FILE__, __LINE__); delete t; }
void ST_avmplus_peephole::test0() { WordcodeEmitter* t = new WordcodeEmitter(core, NULL); t->emitOp1(WOP_getlocal, 5); t->emitOp1(WOP_getlocal, 4); t->emitOp1(WOP_getlocal, 65536); t->emitOp1(WOP_getlocal, 7); t->emitOp1(WOP_getlocal, 6); uintptr_t* code; uint32_t len = (uint32_t)t->epilogue(&code); #line 76 "ST_avmplus_peephole.st" verifyPass(len == 6, "len == 6", __FILE__, __LINE__); #line 77 "ST_avmplus_peephole.st" verifyPass(code[0] == NEW_OPCODE(WOP_get2locals), "code[0] == NEW_OPCODE(WOP_get2locals)", __FILE__, __LINE__); #line 78 "ST_avmplus_peephole.st" verifyPass(code[1] == ((4 << 16) | 5), "code[1] == ((4 << 16) | 5)", __FILE__, __LINE__); #line 79 "ST_avmplus_peephole.st" verifyPass(code[2] == NEW_OPCODE(WOP_getlocal), "code[2] == NEW_OPCODE(WOP_getlocal)", __FILE__, __LINE__); #line 80 "ST_avmplus_peephole.st" verifyPass(code[3] == 65536, "code[3] == 65536", __FILE__, __LINE__); #line 81 "ST_avmplus_peephole.st" verifyPass(code[4] == NEW_OPCODE(WOP_get2locals), "code[4] == NEW_OPCODE(WOP_get2locals)", __FILE__, __LINE__); #line 82 "ST_avmplus_peephole.st" verifyPass(code[5] == ((6 << 16) | 7), "code[5] == ((6 << 16) | 7)", __FILE__, __LINE__); delete t; }
void WordcodeEmitter::emitLookupswitch(const uint8_t *pc) { #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER // Avoid a lot of hair by flushing before LOOKUPSWITCH and not peepholing after. peepFlush(); #endif const uint8_t* base_pc = pc; pc++; uint32_t base_offset = uint32_t(buffer_offset + (dest - buffers->data)); intptr_t default_offset = AvmCore::readS24(pc); pc += 3; uint32_t case_count = AvmCore::readU30(pc); CHECK(3); *dest++ = NEW_OPCODE(OP_lookupswitch); emitRelativeOffset(base_offset, base_pc, default_offset); *dest++ = case_count; for ( uint32_t i=0 ; i <= case_count ; i++ ) { intptr_t offset = AvmCore::readS24(pc); pc += 3; CHECK(1); emitRelativeOffset(base_offset, base_pc, offset); } #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER // need a forward declaration for toplevel. // AvmAssert(toplevel[OP_lookupswitch] == 0); #endif }
void WordcodeEmitter::emitGetscopeobject(const uint8_t *pc) { CHECK(2); pc++; *dest++ = NEW_OPCODE(OP_getscopeobject); *dest++ = *pc++; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(OP_getscopeobject, dest-2); #endif }
void WordcodeEmitter::emitPushshort(const uint8_t *pc) { CHECK(2); pc++; *dest++ = NEW_OPCODE(WOP_pushbits); *dest++ = (intptr_t)((int16_t)AvmCore::readU30(pc) << 3) | kIntegerType; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(WOP_pushbits, dest-2); #endif }
// These take no arguments void WordcodeEmitter::emitOp0(const uint8_t *pc, WordOpcode opcode) { #ifdef _DEBUG AvmAssert(wopAttrs[opcode].width == 1); #endif // _DEBUG (void)pc; CHECK(1); *dest++ = NEW_OPCODE(opcode); #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(opcode, dest-1); #endif }
// These take one U30 argument, and the argument is explicitly passed here (result of optimization) void WordcodeEmitter::emitOp1(WordOpcode opcode, uint32_t operand) { #ifdef _DEBUG AvmAssert(wopAttrs[opcode].width == 2); #endif // _DEBUG CHECK(2); *dest++ = NEW_OPCODE(opcode); *dest++ = (intptr_t)(int32_t)operand; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(opcode, dest-2); #endif }
void WordcodeEmitter::emitOp2(WordOpcode opcode, uint32_t op1, uint32_t op2) { #ifdef _DEBUG AvmAssert(wopAttrs[opcode].width == 3); #endif CHECK(3); *dest++ = NEW_OPCODE(opcode); *dest++ = (intptr_t)(int32_t)op1; *dest++ = (intptr_t)(int32_t)op2; #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(opcode, dest-3); #endif }
// These take one U30 argument void WordcodeEmitter::emitOp1(const uint8_t *pc, WordOpcode opcode) { #ifdef _DEBUG AvmAssert(wopAttrs[opcode].width == 2); #endif // _DEBUG CHECK(2); pc++; *dest++ = NEW_OPCODE(opcode); *dest++ = (intptr_t)(int32_t)AvmCore::readU30(pc); #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(opcode, dest-2); #endif }
void WordcodeEmitter::emitDebug(const uint8_t *pc) { CHECK(5); pc++; uint8_t debug_type = *pc++; uint32_t index = AvmCore::readU30(pc); uint8_t reg = *pc++; uint32_t extra = AvmCore::readU30(pc); // 4 separate operands to match the value in the operand count table, // though obviously we could pack debug_type and reg into one word and // we could also omit extra. *dest++ = NEW_OPCODE(OP_debug); *dest++ = debug_type; *dest++ = (intptr_t)(int32_t)index; *dest++ = (intptr_t)(int32_t)reg; *dest++ = (intptr_t)(int32_t)extra; }
// These take one S24 argument that is PC-relative. If the offset is negative // then the target must be a LABEL instruction, and we can just look it up. // Otherwise, we enter the target offset into an ordered list with the current // transformed PC and the location to backpatch. void WordcodeEmitter::emitRelativeJump(const uint8_t *pc, WordOpcode opcode) { #ifdef _DEBUG AvmAssert(wopAttrs[opcode].jumps); #endif CHECK(2); pc++; intptr_t offset = (intptr_t)AvmCore::readS24(pc); pc += 3; *dest++ = NEW_OPCODE(opcode); uintptr_t base_offset = uintptr_t(buffer_offset + (dest - buffers->data) + 1); emitRelativeOffset(base_offset, pc, offset); #ifdef AVMPLUS_PEEPHOLE_OPTIMIZER peep(opcode, dest-2); AvmAssert(state == 0); // Never allow a jump instruction to be in the middle of a match #endif }
bool WordcodeEmitter::commit(uint32_t action) { switch (action) { case 1: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 4) { S[0] = WOP_getlocal0 + I[0][1]; R[0] = NEW_OPCODE(WOP_getlocal0 + I[0][1]); return replace(1,1); } return false; case 2: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_get2locals; R[0] = NEW_OPCODE(WOP_get2locals); R[1] = (I[1][1] << 16) | I[0][1]; return replace(2,2); } return false; case 3: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 1024 && I[1][1] < 1024 && I[2][1] < 1024) { S[0] = WOP_get3locals; R[0] = NEW_OPCODE(WOP_get3locals); R[1] = (I[2][1] << 20) | (I[1][1] << 10) | I[0][1]; return replace(3,2); } return false; case 4: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal) && I[3][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 256 && I[1][1] < 256 && I[2][1] < 256 && I[3][1] < 256) { S[0] = WOP_get4locals; R[0] = NEW_OPCODE(WOP_get4locals); R[1] = (I[3][1] << 24) | (I[2][1] << 16) | (I[1][1] << 8) | I[0][1]; return replace(4,2); } return false; case 5: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal) && I[3][0] == NEW_OPCODE(WOP_getlocal) && I[4][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 64 && I[1][1] < 64 && I[2][1] < 64 && I[3][1] < 64 && I[4][1] < 64) { S[0] = WOP_get5locals; R[0] = NEW_OPCODE(WOP_get5locals); R[1] = (I[4][1] << 24) | (I[3][1] << 18) | (I[2][1] << 12) | (I[1][1] << 6) | I[0][1]; return replace(5,2); } return false; case 6: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_add)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_add_ll; R[0] = NEW_OPCODE(WOP_add_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 7: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_add) && I[3][0] == NEW_OPCODE(WOP_setlocal)); if (I[0][1] < 1024 && I[1][1] < 1024 && I[3][1] < 1024) { S[0] = WOP_add_set_lll; R[0] = NEW_OPCODE(WOP_add_set_lll); R[1] = (I[3][1] << 20) | (I[1][1] << 10) | I[0][1]; return replace(4,2); } return false; case 8: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_subtract)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_subtract_ll; R[0] = NEW_OPCODE(WOP_subtract_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 9: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_multiply)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_multiply_ll; R[0] = NEW_OPCODE(WOP_multiply_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 10: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_divide)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_divide_ll; R[0] = NEW_OPCODE(WOP_divide_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 11: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_modulo)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_modulo_ll; R[0] = NEW_OPCODE(WOP_modulo_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 12: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitand)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitand_ll; R[0] = NEW_OPCODE(WOP_bitand_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 13: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitor)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitor_ll; R[0] = NEW_OPCODE(WOP_bitor_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 14: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitxor)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitxor_ll; R[0] = NEW_OPCODE(WOP_bitxor_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 15: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_iflt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_iflt_ll; R[0] = NEW_OPCODE(WOP_iflt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 16: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnlt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnlt_ll; R[0] = NEW_OPCODE(WOP_ifnlt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 17: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifle)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifle_ll; R[0] = NEW_OPCODE(WOP_ifle_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 18: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnle)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnle_ll; R[0] = NEW_OPCODE(WOP_ifnle_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 19: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifgt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifgt_ll; R[0] = NEW_OPCODE(WOP_ifgt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 20: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifngt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifngt_ll; R[0] = NEW_OPCODE(WOP_ifngt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 21: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifge)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifge_ll; R[0] = NEW_OPCODE(WOP_ifge_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 22: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnge)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnge_ll; R[0] = NEW_OPCODE(WOP_ifnge_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 23: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifeq)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifeq_ll; R[0] = NEW_OPCODE(WOP_ifeq_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 24: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifne)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifne_ll; R[0] = NEW_OPCODE(WOP_ifne_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 25: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifstricteq)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifstricteq_ll; R[0] = NEW_OPCODE(WOP_ifstricteq_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 26: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifstrictne)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifstrictne_ll; R[0] = NEW_OPCODE(WOP_ifstrictne_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 27: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_add)); if (true) { S[0] = WOP_add_lb; R[0] = NEW_OPCODE(WOP_add_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 28: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_subtract)); if (true) { S[0] = WOP_subtract_lb; R[0] = NEW_OPCODE(WOP_subtract_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 29: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_multiply)); if (true) { S[0] = WOP_multiply_lb; R[0] = NEW_OPCODE(WOP_multiply_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 30: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_divide)); if (true) { S[0] = WOP_divide_lb; R[0] = NEW_OPCODE(WOP_divide_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 31: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitand)); if (true) { S[0] = WOP_bitand_lb; R[0] = NEW_OPCODE(WOP_bitand_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 32: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitor)); if (true) { S[0] = WOP_bitor_lb; R[0] = NEW_OPCODE(WOP_bitor_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 33: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitxor)); if (true) { S[0] = WOP_bitxor_lb; R[0] = NEW_OPCODE(WOP_bitxor_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 34: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_iflt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_iflt_lb; R[0] = NEW_OPCODE(WOP_iflt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 35: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnlt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnlt_lb; R[0] = NEW_OPCODE(WOP_ifnlt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 36: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifle)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifle_lb; R[0] = NEW_OPCODE(WOP_ifle_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 37: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnle)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnle_lb; R[0] = NEW_OPCODE(WOP_ifnle_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 38: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifgt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifgt_lb; R[0] = NEW_OPCODE(WOP_ifgt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 39: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifngt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifngt_lb; R[0] = NEW_OPCODE(WOP_ifngt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 40: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifge)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifge_lb; R[0] = NEW_OPCODE(WOP_ifge_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 41: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnge)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnge_lb; R[0] = NEW_OPCODE(WOP_ifnge_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 42: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifeq)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifeq_lb; R[0] = NEW_OPCODE(WOP_ifeq_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 43: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifne)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifne_lb; R[0] = NEW_OPCODE(WOP_ifne_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 44: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifstricteq)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifstricteq_lb; R[0] = NEW_OPCODE(WOP_ifstricteq_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 45: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifstrictne)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifstrictne_lb; R[0] = NEW_OPCODE(WOP_ifstrictne_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 46: AvmAssert(I[0][0] == NEW_OPCODE(WOP_setlocal)); if (I[0][1] < 4) { S[0] = WOP_setlocal0 + I[0][1]; R[0] = NEW_OPCODE(WOP_setlocal0 + I[0][1]); return replace(1,1); } return false; case 47: AvmAssert(I[0][0] == NEW_OPCODE(WOP_setlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] == I[1][1]) { S[0] = WOP_storelocal; R[0] = NEW_OPCODE(WOP_storelocal); R[1] = I[0][1]; return replace(2,2); } return false; case 48: AvmAssert(I[0][0] == NEW_OPCODE(WOP_swap) && I[1][0] == NEW_OPCODE(WOP_pop)); if (true) { S[0] = WOP_swap_pop; R[0] = NEW_OPCODE(WOP_swap_pop); return replace(2,1); } return false; default: AvmAssert(!"Should not happen"); return false; } }