protected short op_call() { int nlocals; int i; short thislocal; if (operands[0] == 0) { /* calls to zero return false */ /* * Can't just return false because call is not treated as a store in * execute_instruction */ zm.set_variable(storevar, ZFALSE); } else { zm.zstack.push(new ZFrameBound(isstore())); zm.zstack.push(new Integer(storevar)); zm.zstack.push(new Integer(zm.pc)); zm.zstack.push(zm.locals); // System.err.print("From "); // System.err.print(Integer.toString(zm.pc, 16)); zm.pc = zm.routine_address(operands[0]); // System.err.print(" calling routine at "); // System.err.println(Integer.toString(zm.pc, 16)); nlocals = zm.get_code_byte(); zm.locals = new short[nlocals]; for (i = 0; i < nlocals; i++) { thislocal = (short) (((zm.get_code_byte() << 8) & 0xFF00) | (zm.get_code_byte() & 0xFF)); if (i < (count - 1)) { zm.locals[i] = operands[i + 1]; } else { zm.locals[i] = thislocal; } } } return ZFALSE; }
protected void decode_second_half() { if (isstore()) storevar = zm.get_code_byte(); if (isbranch()) { branchoffset = zm.get_code_byte(); branchtype = (branchoffset & 0x80) != 0; if ((branchoffset & 0x40) != 0) /* positive 6-bit number */ branchoffset &= 0x3F; else if ((branchoffset & 0x20) != 0) /* negative 14-bit number */ branchoffset = (short) (0xC000 | ((branchoffset << 8) | (((short) zm.get_code_byte()) & 0xFF))); else /* positive 14-bit number */ branchoffset = (short) (((branchoffset & 0x3F) << 8) | (((short) zm.get_code_byte()) & 0xFF)); } }
protected void decode_first_half() { int opcode; int optype, optypes; int optypes2 = 0; /* It takes a kludge to handle a kludge */ int optypebytes; int isextended = 0; opcode = zm.get_code_byte() & 0xFF; if (opcode == OP_EXTENDED) { isextended = 0xC0; } switch (isextended | opcode & 0xC0) { case 0xC0: /* variable form */ if (isextended != 0xC0) { opnum = opcode; } else { opnum = (0x100 | (zm.get_code_byte() & 0xFF)); } if ((opcode & 0x20) == 0) { /* 2OP */ /* * note that variable-form je can have more than two arguments, though * it is a 2OP */ opnum = opcode & 0x1F; } count = 0; optypes = zm.get_code_byte(); if ((opnum == OP_CALL_VS2) || (opnum == OP_CALL_VN2)) { optypebytes = 2; optypes2 = zm.get_code_byte(); } else optypebytes = 1; while (optypebytes-- != 0) { optype = (optypes & 0xC0) >> 6; if (optype == zm.OP_OMITTED) break; operands[count++] = zm.get_operand(optype); optype = (optypes & 0x30) >> 4; if (optype == zm.OP_OMITTED) break; operands[count++] = zm.get_operand(optype); optype = (optypes & 0x0C) >> 2; if (optype == zm.OP_OMITTED) break; operands[count++] = zm.get_operand(optype); optype = (optypes & 0x03); if (optype == zm.OP_OMITTED) break; operands[count++] = zm.get_operand(optype); optypes = optypes2; } break; case 0x80: /* short form */ optype = (opcode & 0x30) >> 4; if (optype == zm.OP_OMITTED) { /* 0OP */ opnum = opcode; count = 0; } else { /* 1OP */ opnum = opcode & 0x8F; count = 1; operands[0] = zm.get_operand(optype); } break; default: /* long form */ /* always 2OP */ opnum = opcode & 0x1F; count = 2; optype = ((opcode & 0x40) >> 6) + 1; operands[0] = zm.get_operand(optype); optype = ((opcode & 0x20) >> 5) + 1; operands[1] = zm.get_operand(optype); } }