asm.emitADD_Reg_Imm(SP, 4);
asm.emitADD_Reg_Imm(SP, WORDSIZE*3);
  private final VM_MachineCode genCode (int compiledMethodId, VM_Method method) {    /* initialization */ {      // TODO!! check register ranges TODO!!      this.method          = method;      klass                = method.getDeclaringClass();      bytecodes            = method.getBytecodes();      bytecodeLength       = bytecodes.length;      bytecodeMap          = new int [bytecodeLength];      if (klass.isBridgeFromNative())	// JNIFunctions need space for bigger prolog & epilog	asm                  = new VM_Assembler(bytecodeLength+10);      else	asm                  = new VM_Assembler(bytecodeLength);      profilerClass        = null; // TODO!! set this correctly      parameterWords       = method.getParameterWords();      parameterWords      += (method.isStatic() ? 0 : 1); // add 1 for this pointer      //      if (VM.VerifyAssertions) VM.assert(parameters == 0); // TODO!!    }    VM_Assembler asm = this.asm; // premature optimization    if (klass.isBridgeFromNative()) {      // replace the normal prologue with a special prolog      VM_JNICompiler.generateGlueCodeForJNIMethod (asm, method, compiledMethodId);      // set some constants for the code generation of the rest of the method      // firstLocalOffset is shifted down because more registers are saved      firstLocalOffset = STACKFRAME_BODY_OFFSET - (VM_JNICompiler.SAVED_GPRS_FOR_JNI<<LG_WORDSIZE) ;    } else {      genPrologue(compiledMethodId);    }    for (bi=0; bi<bytecodeLength;) {       bytecodeMap[bi] = asm.getMachineCodeIndex();      asm.resolveForwardReferences(bi);      biStart = bi;      int code = fetch1ByteUnsigned();      // if (VM.runningVM) VM.sysWrite("\n at: " + VM_Lister.decimal(biStart) + " = " + VM_Lister.hex((byte) code) + "\n");      switch (code) {      case 0x00: /* nop */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "nop");	break;      }      case 0x01: /* aconst_null */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aconst_null ");	asm.emitPUSH_Imm(0);	break;      }      case 0x02: /* iconst_m1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_m1 ");	asm.emitPUSH_Imm(-1);	break;      }      case 0x03: /* iconst_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_0 ");	asm.emitPUSH_Imm(0);	break;      }      case 0x04: /* iconst_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_1 ");	asm.emitPUSH_Imm(1);	break;      }      case 0x05: /* iconst_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_2 ");	asm.emitPUSH_Imm(2);	break;      }      case 0x06: /* iconst_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_3 ");	asm.emitPUSH_Imm(3);	break;      }      case 0x07: /* iconst_4 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_4 ");	asm.emitPUSH_Imm(4);	break;      }      case 0x08: /* iconst_5 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iconst_5 ");	asm.emitPUSH_Imm(5);	break;      }      case 0x09: /* lconst_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lconst_0 ");  // floating-point 0 is long 0	asm.emitPUSH_Imm(0);	asm.emitPUSH_Imm(0);	break;      }      case 0x0a: /* lconst_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lconst_1 ");	asm.emitPUSH_Imm(0);  // high part	asm.emitPUSH_Imm(1);  //  low part	break;      }      case 0x0b: /* fconst_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fconst_0");	asm.emitPUSH_Imm(0);	break;      }      case 0x0c: /* fconst_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fconst_1");	asm.emitPUSH_Imm(0x3f800000);	break;      }      case 0x0d: /* fconst_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fconst_2");	asm.emitPUSH_Imm(0x40000000);	break;      }      case 0x0e: /* dconst_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dconst_0");	asm.emitPUSH_Imm(0x00000000);	asm.emitPUSH_Imm(0x00000000);	break;      }      case 0x0f: /* dconst_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dconst_1");	asm.emitPUSH_Imm(0x3ff00000);	asm.emitPUSH_Imm(0x00000000);	break;      }      case 0x10: /* bipush */ {	int val = fetch1ByteSigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "bipush " + VM_Lister.decimal(val));	asm.emitPUSH_Imm(val);	break;      }      case 0x11: /* sipush */ {	int val = fetch2BytesSigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "sipush " + VM_Lister.decimal(val));	asm.emitPUSH_Imm(val);	break;      }      case 0x12: /* ldc */ {	int index = fetch1ByteUnsigned();	int offset = klass.getLiteralOffset(index);	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ldc " + VM_Lister.decimal(index));	asm.emitPUSH_RegDisp(JTOC, offset);   	break;      }      case 0x13: /* ldc_w */ {	int index = fetch2BytesUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ldc_w " + VM_Lister.decimal(index));	int offset = klass.getLiteralOffset(index);	asm.emitPUSH_RegDisp(JTOC, offset);   	break;      }      case 0x14: /* ldc2_w */ {	int index = fetch2BytesUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ldc2_w " + VM_Lister.decimal(index));	int offset = klass.getLiteralOffset(index);	asm.emitPUSH_RegDisp(JTOC, offset+4); // high part of the long	asm.emitPUSH_RegDisp(JTOC, offset);   // low part of the long	break;      }      case 0x15: /* iload */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iload " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPUSH_RegDisp(FP,offset);	break;      }      case 0x16: /* lload */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lload " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(index+1);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x17: /* fload */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fload " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPUSH_RegDisp (FP, offset);	break;      }      case 0x18: /* dload */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dload " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(index+1);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x19: /* aload */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aload " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPUSH_RegDisp(FP, offset);	break;      }      case 0x1a: /* iload_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iload_0");	int offset = localOffset(0);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x1b: /* iload_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iload_1");	int offset = localOffset(1);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x1c: /* iload_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iload_2");	int offset = localOffset(2);	asm.emitPUSH_RegDisp (FP, offset);	break;      }      case 0x1d: /* iload_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iload_3");	int offset = localOffset(3);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x1e: /* lload_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lload_0");	int offset = localOffset(0);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(1);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x1f: /* lload_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lload_1");	int offset = localOffset(1);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(2);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x20: /* lload_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lload_2");	int offset = localOffset(2);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(3);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x21: /* lload_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lload_3");	int offset = localOffset(3);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(4);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x22: /* fload_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fload_0");	int offset = localOffset(0);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x23: /* fload_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fload_1");	int offset = localOffset(1);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x24: /* fload_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fload_2");	int offset = localOffset(2);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x25: /* fload_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fload_3");	int offset = localOffset(3);	asm.emitPUSH_RegDisp ( FP, offset);	break;      }      case 0x26: /* dload_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dload_0");	int offset = localOffset(0);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(1);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x27: /* dload_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dload_1");	int offset = localOffset(1);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(2);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x28: /* dload_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dload_2");	int offset = localOffset(2);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(3);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x29: /* dload_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dload_3");	int offset = localOffset(3);	asm.emitPUSH_RegDisp(FP, offset); // high part	offset = localOffset(4);	asm.emitPUSH_RegDisp(FP, offset); //  low part	break;      }      case 0x2a: /* aload_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aload_0");	int offset = localOffset(0);	asm.emitPUSH_RegDisp(FP, offset);	break;      }      case 0x2b: /* aload_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aload_1");	int offset = localOffset(1);	asm.emitPUSH_RegDisp(FP, offset);	break;      }                 case 0x2c: /* aload_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aload_2");	int offset = localOffset(2);	asm.emitPUSH_RegDisp(FP, offset);	break;      }      case 0x2d: /* aload_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aload_3");	int offset = localOffset(3);	asm.emitPUSH_RegDisp(FP, offset);	break;      }       case 0x2e: /* iaload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iaload");	asm.emitPOP_Reg(T0);                            // T0 is index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0, S0);              // T0 is index, S0 is address of array	asm.emitPUSH_RegIdx(S0, T0, asm.WORD, 0);          // push desired int array element	break;      }      case 0x2f: /* laload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "laload");	asm.emitPOP_Reg(T0);                            // T0 is index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0,S0);               // T0 is index, S0 is address of array	asm.emitPUSH_RegIdx(S0, T0, asm.LONG, WORDSIZE);   // load high part of desired long array element	asm.emitPUSH_RegIdx(S0, T0, asm.LONG, 0);          // load low part of desired long array element	break;      }      case 0x30: /* faload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "faload");	asm.emitPOP_Reg(T0);                            // T0 is array index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0, S0);              // T0 is index, S0 is address of array	asm.emitPUSH_RegIdx(S0, T0, asm.WORD, 0);          // push desired float array element	break;      }      case 0x31: /* daload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "daload");	asm.emitPOP_Reg(T0);                            // T0 is index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0,S0);               // T0 is index, S0 is address of array	asm.emitPUSH_RegIdx(S0, T0, asm.LONG, WORDSIZE);   // load high part of double	asm.emitPUSH_RegIdx(S0, T0, asm.LONG, 0);          // load low part of double	break;      }      case 0x32: /* aaload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aaload");	asm.emitPOP_Reg(T0);                            // T0 is array index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0, S0);              // T0 is index, S0 is address of array	asm.emitPUSH_RegIdx(S0, T0, asm.WORD, 0);          // push desired int array element	break;      }      case 0x33: /* baload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "baload");	asm.emitPOP_Reg(T0);                                       // T0 is array index	asm.emitPOP_Reg(S0);                                       // S0 is array ref	genBoundsCheck(asm, T0, S0);                             // T0 is index, S0 is address of array	asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, asm.BYTE, 0);    // load byte and sign extend to a 32 bit word	asm.emitPUSH_Reg(T1);                                      // push onto stack	break;      }      case 0x34: /* caload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "caload");	asm.emitPOP_Reg(T0);                                       // T0 is array index	asm.emitPOP_Reg(S0);                                       // S0 is array ref	genBoundsCheck(asm, T0, S0);                             // T0 is index, S0 is address of array	asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, asm.SHORT, 0);   // load halfword without sign extend to a 32 bit word	asm.emitPUSH_Reg(T1);                                      // push onto stack	break;      }      case 0x35: /* saload */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "saload");	asm.emitPOP_Reg(T0);                                       // T0 is array index	asm.emitPOP_Reg(S0);                                       // S0 is array ref	genBoundsCheck(asm, T0,S0);                              // check array length vs index	asm.emitMOVSX_Reg_RegIdx_Word(T1, S0, T0, asm.SHORT, 0);   // load halfword sign extend to a 32 bit word	asm.emitPUSH_Reg(T1);                                      // push onto stack	break;      }      case 0x36: /* istore */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "istore " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x37: /* lstore */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lstore " + VM_Lister.decimal(index));	int offset = localOffset(index+1);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(index);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x38: /* fstore */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fstore " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x39: /* dstore */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dstore " + VM_Lister.decimal(index));	int offset = localOffset(index+1);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(index);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x3a: /* astore */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "astore " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x3b: /* istore_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "istore_0");	int offset = localOffset(0);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x3c: /* istore_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "istore_1");	int offset = localOffset(1);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x3d: /* istore_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "istore_2");	int offset = localOffset(2);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x3e: /* istore_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "istore_3");	int offset = localOffset(3);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x3f: /* lstore_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lstore_0");	int offset = localOffset(1);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(0);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x40: /* lstore_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lstore_1");	int offset = localOffset(2);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(1);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x41: /* lstore_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lstore_2");	int offset = localOffset(3);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(2);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }       case 0x42: /* lstore_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lstore_3");	int offset = localOffset(4);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(3);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x43: /* fstore_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fstore_0");	int offset = localOffset(0);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x44: /* fstore_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fstore_1");	int offset = localOffset(1);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x45: /* fstore_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fstore_2");	int offset = localOffset(2);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x46: /* fstore_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fstore_3");	int offset = localOffset(3);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x47: /* dstore_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dstore_0");	int offset = localOffset(1);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(0);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x48: /* dstore_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dstore_1");	int offset = localOffset(2);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(1);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x49: /* dstore_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dstore_2");	int offset = localOffset(3);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(2);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x4a: /* dstore_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dstore_3");	int offset = localOffset(4);	asm.emitPOP_RegDisp(FP, offset); // high part	offset = localOffset(3);	asm.emitPOP_RegDisp(FP, offset); //  low part	break;      }      case 0x4b: /* astore_0 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "astore_0");	int offset = localOffset(0);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x4c: /* astore_1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "astore_1");	int offset = localOffset(1);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x4d: /* astore_2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "astore_2");	int offset = localOffset(2);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x4e: /* astore_3 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "astore_3");	int offset = localOffset(3);	asm.emitPOP_RegDisp (FP, offset);	break;      }      case 0x4f: /* iastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iastore");	asm.emitPOP_Reg(T1);                      // T1 is the value	asm.emitPOP_Reg(T0);                      // T0 is array index	//asm.emitPOP_Reg(S0);                    // S0 is array ref	asm.emitMOV_Reg_RegDisp(S0, SP, 0);                     // S0 is the array ref	genBoundsCheck(asm, T0,S0);         // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg(S0, T0, asm.WORD, 0, T1); // [S0 + T0<<2] <- T1        asm.emitADD_Reg_Imm(SP, 4);	break;      }      case 0x50: /* lastore */ { 	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lastore"); 	asm.emitMOV_Reg_RegDisp(T0, SP, 8);                      // T0 is the array index	asm.emitMOV_Reg_RegDisp(S0, SP, 12);                     // S0 is the array ref	genBoundsCheck(asm, T0,S0);	asm.emitPOP_Reg(T1);                             // low part	asm.emitMOV_RegIdx_Reg(S0, T0, asm.LONG, 0, T1);        // [S0 + T0<<3 + 0] <- T1 store low part into array i.e.  	asm.emitPOP_Reg(T1);                             // high part	asm.emitMOV_RegIdx_Reg(S0, T0, asm.LONG, WORDSIZE, T1); // [S0 + T0<<3 + 4] <- T1 store high part into array i.e. 	asm.emitADD_Reg_Imm(SP, WORDSIZE*2);                // remove index and ref from the stack	break;      }      case 0x51: /* fastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fastore");	asm.emitPOP_Reg(T1);                      // T1 is the value	asm.emitPOP_Reg(T0);                      // T0 is array index	asm.emitPOP_Reg(S0);                      // S0 is array ref	genBoundsCheck(asm, T0, S0);        // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg(S0, T0, asm.WORD, 0, T1); // [S0 + T0<<2] <- T1	break;      }      case 0x52: /* dastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dastore");	asm.emitMOV_Reg_RegDisp(T0, SP, 8);                      // T0 is the array index	asm.emitMOV_Reg_RegDisp(S0, SP, 12);                     // S0 is the array ref	genBoundsCheck(asm, T0,S0);	asm.emitPOP_Reg(T1);                             // low part	asm.emitMOV_RegIdx_Reg(S0, T0, asm.LONG, 0, T1);        // [S0 + T0<<3 + 0] <- T1 store low part into array i.e.  	asm.emitPOP_Reg(T1);                             // high part	asm.emitMOV_RegIdx_Reg(S0, T0, asm.LONG, WORDSIZE, T1); // [S0 + T0<<3 + 4] <- T1 store high part into array i.e. 	asm.emitADD_Reg_Imm(SP, WORDSIZE*2);                 // remove index and ref from the stack	break;      }      case 0x53: /* aastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "aastore");	asm.emitPUSH_RegDisp(SP, 2<<LG_WORDSIZE);                    // duplicate array ref	asm.emitPUSH_RegDisp(SP, 1<<LG_WORDSIZE);                    // duplicate value	genParameterRegisterLoad(2);                         // pass 2 parameter	asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.checkstoreOffset); // checkstore(array ref, value)	asm.emitPOP_Reg(T1);                                     // T1 is the value	asm.emitPOP_Reg(T0);                                     // T0 is array index	asm.emitPOP_Reg(S0);                                     // S0 is array ref	genBoundsCheck(asm, T0, S0);                       // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg(S0, T0, asm.WORD, 0, T1);                // [S0 + T0<<2] <- T1	break;      }      case 0x54: /* bastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "bastore");	asm.emitPOP_Reg(T1);                            // T1 is the value	asm.emitPOP_Reg(T0);                            // T0 is array index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0,S0);               // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg_Byte(S0, T0, asm.BYTE, 0, T1);      // store byte element into array i.e. [S0 +T0] <- T1 (byte)	break;      }      case 0x55: /* castore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "castore");	asm.emitPOP_Reg(T1);                            // T1 is the value	asm.emitPOP_Reg(T0);                            // T0 is array index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0,S0);               // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg_Word(S0, T0, asm.SHORT, 0, T1);     // store halfword element into array i.e. [S0 +T0] <- T1 (halfword)	break;      }      case 0x56: /* sastore */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "sastore");	asm.emitPOP_Reg(T1);                            // T1 is the value	asm.emitPOP_Reg(T0);                            // T0 is array index	asm.emitPOP_Reg(S0);                            // S0 is array ref	genBoundsCheck(asm, T0,S0);               // T0 is index, S0 is address of array	asm.emitMOV_RegIdx_Reg_Word(S0, T0, asm.SHORT, 0, T1);     // store halfword element into array i.e. [S0 +T0] <- T1 (halfword)	break;      }      case 0x57: /* pop */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "pop");	asm.emitPOP_Reg(T0);	break;      }      case 0x58: /* +++ pop2 +++ */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "pop2");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(T0);	break;      }      case 0x59: /* dup */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup");	asm.emitMOV_Reg_RegInd (T0, SP);	asm.emitPUSH_Reg(T0);	break;      }       case 0x5a: /* dup_x1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup_x1");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(S0);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	break;      }      case 0x5b: /* dup_x2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup_x2");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T1);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(T1);	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	break;      }      case 0x5c: /* dup2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup2");	asm.emitMOV_Reg_RegDisp (T0, SP, 4);	asm.emitMOV_Reg_RegInd (S0, SP);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(S0);	break;      }      case 0x5d: /* dup2_x1 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup2_x1");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T1);	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(T1);	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	break;      }      case 0x5e: /* dup2_x2 */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dup2_x2");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T1);	asm.emitPOP_Reg(JTOC);                  // JTOC is scratch register	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(JTOC);	asm.emitPUSH_Reg(T1);	asm.emitPUSH_Reg(S0);	asm.emitPUSH_Reg(T0);	asm.emitMOV_Reg_RegDisp (JTOC, PR, VM_Entrypoints.jtocOffset); // restore JTOC register	break;      }      case 0x5f: /* swap */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "swap");	asm.emitPOP_Reg(T0);	asm.emitPOP_Reg(S0);	asm.emitPUSH_Reg(T0);	asm.emitPUSH_Reg(S0);	break;      }      case 0x60: /* iadd */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iadd");	asm.emitPOP_Reg(T0);	asm.emitADD_RegInd_Reg(SP, T0);	break;      }      case 0x61: /* ladd */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ladd");	asm.emitPOP_Reg(T0);                 // the low half of one long	asm.emitPOP_Reg(S0);                 // the high half	asm.emitADD_RegInd_Reg(SP, T0);          // add low halves	asm.emitADC_RegDisp_Reg(SP, WORDSIZE, S0);   // add high halves with carry	break;      }      case 0x62: /* fadd */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fadd");	asm.emitFLD_Reg_RegInd (FP0, SP);        // FPU reg. stack <- value2	asm.emitFADD_Reg_RegDisp(FP0, SP, WORDSIZE); // FPU reg. stack += value1	asm.emitPOP_Reg   (T0);           // discard 	asm.emitFSTP_RegInd_Reg(SP, FP0);        // POP FPU reg. stack onto stack	break;      }      case 0x63: /* dadd */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dadd");	asm.emitFLD_Reg_RegInd_Quad (FP0, SP);        // FPU reg. stack <- value2	asm.emitFADD_Reg_RegDisp_Quad(FP0, SP, 8);        // FPU reg. stack += value1	asm.emitADD_Reg_Imm(SP, 2*WORDSIZE);  // shrink the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);        // POP FPU reg. stack onto stack	break;      }      case 0x64: /* isub */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "isub");	asm.emitPOP_Reg(T0);	asm.emitSUB_RegInd_Reg(SP, T0);	break;      }      case 0x65: /* lsub */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lsub");	asm.emitPOP_Reg(T0);                 // the low half of one long	asm.emitPOP_Reg(S0);                 // the high half	asm.emitSUB_RegInd_Reg(SP, T0);          // subtract low halves	asm.emitSBB_RegDisp_Reg(SP, WORDSIZE, S0);   // subtract high halves with borrow	break;      }      case 0x66: /* fsub */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fsub");	asm.emitFLD_Reg_RegDisp (FP0, SP, WORDSIZE); // FPU reg. stack <- value1	asm.emitFSUB_Reg_RegDisp(FP0, SP, 0);        // FPU reg. stack -= value2	asm.emitPOP_Reg   (T0);           // discard 	asm.emitFSTP_RegInd_Reg(SP, FP0);        // POP FPU reg. stack onto stack	break;      }      case 0x67: /* dsub */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dsub");	asm.emitFLD_Reg_RegDisp_Quad (FP0, SP, 8);          // FPU reg. stack <- value1	asm.emitFSUB_Reg_RegDisp_Quad(FP0, SP, 0);          // FPU reg. stack -= value2	asm.emitADD_Reg_Imm   (SP, 2*WORDSIZE); // shrink the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);          // POP FPU reg. stack onto stack	break;      }      case 0x68: /* imul */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "imul");	asm.emitPOP_Reg (T0);	asm.emitIMUL2_Reg_RegInd(T0, SP);	asm.emitMOV_RegInd_Reg (SP, T0);	break;      }      case 0x69: /* lmul */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lmul");	// 0: JTOC is used as scratch registers (see 14)	// 1: load value1.low temp0, i.e., save value1.low	// 2: eax <- temp0 eax is value1.low	// 3: edx:eax <- eax * value2.low (product of the two low halves)	// 4: store eax which is  result.low into place --> value1.low is destroyed	// 5: temp1 <- edx which is the carry of the product of the low halves	// aex and edx now free of results	// 6: aex <- temp0 which is still value1.low	// 7: pop into aex aex <- value2.low  --> value2.low is sort of destroyed	// 8: edx:eax <- eax * value1.hi  (value2.low * value1.hi)	// 9: temp1 += aex	// 10: pop into eax; eax <- value2.hi -> value2.hi is sort of destroyed	// 11: edx:eax <- eax * temp0 (value2.hi * value1.low)	// 12: temp1 += eax  temp1 is now result.hi	// 13: store result.hi	// 14: restore JTOC	if (VM.VerifyAssertions) VM.assert(S0 != EAX);	if (VM.VerifyAssertions) VM.assert(S0 != EDX);	asm.emitMOV_Reg_RegDisp (JTOC, SP, 8);          // step 1: JTOC is temp0	asm.emitMOV_Reg_Reg (EAX, JTOC);            // step 2	asm.emitMUL_Reg_RegInd(EAX, SP);    // step 3	asm.emitMOV_RegDisp_Reg (SP, 8, EAX);           // step 4	asm.emitMOV_Reg_Reg (S0, EDX);              // step 5: S0 is temp1	asm.emitMOV_Reg_Reg (EAX, JTOC);            // step 6	asm.emitPOP_Reg (EAX);                  // step 7: SP changed!	asm.emitIMUL1_Reg_RegDisp(EAX, SP, 8);// step 8	asm.emitADD_Reg_Reg (S0, EAX);      // step 9	asm.emitPOP_Reg (EAX);                  // step 10: SP changed!	asm.emitIMUL1_Reg_Reg(EAX, JTOC);    // step 11	asm.emitADD_Reg_Reg (S0, EAX);      // step 12	asm.emitMOV_RegDisp_Reg (SP, 4, S0);            // step 13	asm.emitMOV_Reg_RegDisp (JTOC, PR, VM_Entrypoints.jtocOffset); // restore JTOC register	break;      }      case 0x6a: /* fmul */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fmul");	asm.emitFLD_Reg_RegInd (FP0, SP);        // FPU reg. stack <- value2	asm.emitFMUL_Reg_RegDisp(FP0, SP, WORDSIZE); // FPU reg. stack *= value1	asm.emitPOP_Reg   (T0);           // discard 	asm.emitFSTP_RegInd_Reg(SP, FP0);        // POP FPU reg. stack onto stack	break;      }      case 0x6b: /* dmul */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dmul");	asm.emitFLD_Reg_RegInd_Quad (FP0, SP);          // FPU reg. stack <- value2	asm.emitFMUL_Reg_RegDisp_Quad(FP0, SP, 8);          // FPU reg. stack *= value1	asm.emitADD_Reg_Imm   (SP, 2*WORDSIZE); // shrink the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);          // POP FPU reg. stack onto stack	break;      }      case 0x6c: /* idiv */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "idiv");	asm.emitPOP_Reg (ECX); // NOTE: can't use symbolic registers because of intel hardware requirements	asm.emitPOP_Reg (EAX);	asm.emitCDQ ();    // sign extend EAX into EDX	asm.emitIDIV_Reg_Reg(EAX, ECX); // compute EAX/ECX - Quotient in EAX, remainder in EDX	asm.emitPUSH_Reg(EAX);	break;      }      case 0x6d: /* ldiv */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ldiv");	int offset = VM_Entrypoints.longDivideOffset;	genParameterRegisterLoad(4); // pass 4 parameter words (2 longs)	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);  // high half	asm.emitPUSH_Reg(T1);  // low half	break;      }      case 0x6e: /* fdiv */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fdiv");	asm.emitFLD_Reg_RegDisp (FP0, SP, WORDSIZE); // FPU reg. stack <- value1	asm.emitFDIV_Reg_RegDisp(FP0, SP, 0);        // FPU reg. stack /= value2	asm.emitPOP_Reg   (T0);           // discard 	asm.emitFSTP_RegInd_Reg(SP, FP0);        // POP FPU reg. stack onto stack	break;      }      case 0x6f: /* ddiv */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ddiv");	asm.emitFLD_Reg_RegDisp_Quad (FP0, SP, 8);          // FPU reg. stack <- value1	asm.emitFDIV_Reg_RegInd_Quad(FP0, SP);          // FPU reg. stack /= value2	asm.emitADD_Reg_Imm   (SP, 2*WORDSIZE); // shrink the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);          // POP FPU reg. stack onto stack	break;      }      case 0x70: /* irem */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "irem");	asm.emitPOP_Reg (ECX); // NOTE: can't use symbolic registers because of intel hardware requirements	asm.emitPOP_Reg (EAX);	asm.emitCDQ ();    // sign extend EAX into EDX	asm.emitIDIV_Reg_Reg(EAX, ECX); // compute EAX/ECX - Quotient in EAX, remainder in EDX	asm.emitPUSH_Reg(EDX);	break;      }      case 0x71: /* lrem */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lrem");	int offset = VM_Entrypoints.longRemainderOffset;	genParameterRegisterLoad(4); // pass 4 parameter words (2 longs)	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);  // high half	asm.emitPUSH_Reg(T1);  // low half	break;      }      case 0x72: /* frem */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "frem"); 	asm.emitFLD_Reg_RegInd (FP0, SP);        // FPU reg. stack <- value2, or a	asm.emitFLD_Reg_RegDisp (FP0, SP, WORDSIZE); // FPU reg. stack <- value1, or b	asm.emitFPREM ();             // FPU reg. stack <- a%b	asm.emitFSTP_RegDisp_Reg(SP, WORDSIZE, FP0); // POP FPU reg. stack (results) onto java stack	asm.emitFSTP_RegInd_Reg(SP, FP0);        // POP FPU reg. stack onto java stack	asm.emitPOP_Reg   (T0);           // shrink the stack (T0 discarded)	break;      }      case 0x73: /* drem */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "drem");	asm.emitFLD_Reg_RegInd_Quad (FP0, SP);          // FPU reg. stack <- value2, or a	asm.emitFLD_Reg_RegDisp_Quad (FP0, SP, 2*WORDSIZE); // FPU reg. stack <- value1, or b	asm.emitFPREM ();               // FPU reg. stack <- a%b	asm.emitFSTP_RegDisp_Reg_Quad(SP, 2*WORDSIZE, FP0); // POP FPU reg. stack (result) onto java stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);         // POP FPU reg. stack onto java stack	asm.emitADD_Reg_Imm   (SP, 2*WORDSIZE); // shrink the stack	break;      }      case 0x74: /* ineg */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ineg");	asm.emitNEG_RegInd(SP); // [SP] <- -[SP]	break;      }      case 0x75: /* lneg */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lneg");	asm.emitNEG_RegDisp(SP, 4);    // [SP+4] <- -[SP+4] or high <- -high	asm.emitNEG_RegInd(SP);    // [SP] <- -[SP] or low <- -low	asm.emitSBB_RegDisp_Imm(SP, 4, 0); // [SP+4] += borrow or high += borrow	break;      }      case 0x76: /* fneg */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fneg");	asm.emitFLD_Reg_RegInd (FP0, SP); // FPU reg. stack <- value1	asm.emitFCHS  ();      // change sign to stop of FPU stack	asm.emitFSTP_RegInd_Reg(SP, FP0); // POP FPU reg. stack onto stack	break;      }      case 0x77: /* dneg */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dneg");	asm.emitFLD_Reg_RegInd_Quad (FP0, SP); // FPU reg. stack <- value1	asm.emitFCHS  ();      // change sign to stop of FPU stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0); // POP FPU reg. stack onto stack	break;      }      case 0x78: /* ishl */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ishl");	if (VM.VerifyAssertions) VM.assert(ECX != T0);	asm.emitPOP_Reg(ECX);	asm.emitSHL_RegInd_Reg(SP, ECX);   // shift T0 left ECX times;  ECX low order 5 bits	break;      }      case 0x79: /* lshl */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lshl");    // l >> n	if (VM.VerifyAssertions) VM.assert (ECX != T0); // ECX is constrained to be the shift count	if (VM.VerifyAssertions) VM.assert (ECX != T1);	if (VM.VerifyAssertions) VM.assert (ECX != JTOC);	// 1: pop shift amount into JTOC (JTOC must be restored at the end)	// 2: pop low half into T0	// 3: pop high half into T1	// 4: ECX <- JTOC, copy the shift count	// 5: JTOC <- JTOC & 32 --> if 0 then shift amount is less than 32	// 6: branch to step 12 if results is zero	// the result is not zero --> the shift amount is greater than 32	// 7: ECX <- ECX XOR JTOC   --> ECX is orginal shift amount minus 32	// 8: T1 <- T0, or replace the high half with the low half.  This accounts for the 32 bit shift	// 9: shift T1 left by ECX bits	// 10: T0 <- 0	// 11: branch to step 14	// 12: shift left double from T0 into T1 by ECX bits.  T0 is unaltered	// 13: shift left T0, the low half, also by ECX bits	// 14: push high half from T1	// 15: push the low half from T0	// 16: restore the JTOC	asm.emitPOP_Reg (JTOC);                 // original shift amount 6 bits	asm.emitPOP_Reg (T0);                   // pop low half 	asm.emitPOP_Reg (T1);                   // pop high half	asm.emitMOV_Reg_Reg (ECX, JTOC);	asm.emitAND_Reg_Imm (JTOC, 32);	VM_ForwardReference fr1 = asm.forwardJcc(asm.EQ);	asm.emitXOR_Reg_Reg (ECX, JTOC);	asm.emitMOV_Reg_Reg (T1, T0);               // low replaces high	asm.emitSHL_Reg_Reg (T1, ECX);	asm.emitXOR_Reg_Reg (T0, T0);	VM_ForwardReference fr2 = asm.forwardJMP();	fr1.resolve(asm);	asm.emitSHLD_Reg_Reg_Reg(T1, T0, ECX);          // shift high half (step 12)	asm.emitSHL_Reg_Reg (T0, ECX);                   // shift low half	fr2.resolve(asm);	asm.emitPUSH_Reg(T1);                   // push high half (step 14)	asm.emitPUSH_Reg(T0);                   // push low half	asm.emitMOV_Reg_RegDisp (JTOC, PR, VM_Entrypoints.jtocOffset); // restore JTOC	break;      }      case 0x7a: /* ishr */ {	// unit test by IArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ishr");	if (VM.VerifyAssertions) VM.assert (ECX != T0);	asm.emitPOP_Reg (ECX);	asm.emitSAR_RegInd_Reg (SP, ECX);  // shift T0 right ECX times;  ECX low order 5 bits	break;      }      case 0x7b: /* lshr */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lshr");	if (VM.VerifyAssertions) VM.assert (ECX != T0); // ECX is constrained to be the shift count	if (VM.VerifyAssertions) VM.assert (ECX != T1);	if (VM.VerifyAssertions) VM.assert (ECX != JTOC);	// 1: pop shift amount into JTOC (JTOC must be restored at the end)	// 2: pop low half into T0	// 3: pop high half into T1	// 4: ECX <- JTOC, copy the shift count	// 5: JTOC <- JTOC & 32 --> if 0 then shift amount is less than 32	// 6: branch to step 13 if results is zero	// the result is not zero --> the shift amount is greater than 32	// 7: ECX <- ECX XOR JTOC   --> ECX is orginal shift amount minus 32	// 8: T0 <- T1, or replace the low half with the high half.  This accounts for the 32 bit shift	// 9: shift T0 right arithmetic by ECX bits	// 10: ECX <- 31	// 11: shift T1 right arithmetic by ECX=31 bits, thus exending the sigh	// 12: branch to step 15	// 13: shift right double from T1 into T0 by ECX bits.  T1 is unaltered	// 14: shift right arithmetic T1, the high half, also by ECX bits	// 15: push high half from T1	// 16: push the low half from T0	// 17: restore JTOC	asm.emitPOP_Reg (JTOC);                 // original shift amount 6 bits	asm.emitPOP_Reg (T0);                   // pop low half 	asm.emitPOP_Reg (T1);                   // pop high	asm.emitMOV_Reg_Reg (ECX, JTOC);	asm.emitAND_Reg_Imm (JTOC, 32);	VM_ForwardReference fr1 = asm.forwardJcc(asm.EQ);	asm.emitXOR_Reg_Reg (ECX, JTOC);	asm.emitMOV_Reg_Reg (T0, T1);               // replace low with high	asm.emitSAR_Reg_Reg (T0, ECX);                   // and shift it	asm.emitMOV_Reg_Imm (ECX, 31);	asm.emitSAR_Reg_Reg (T1, ECX);                   // set high half	VM_ForwardReference fr2 = asm.forwardJMP();	fr1.resolve(asm);	asm.emitSHRD_Reg_Reg_Reg(T0, T1, ECX);          // shift low half (step 13)	asm.emitSAR_Reg_Reg (T1, ECX);                   // shift high half	fr2.resolve(asm);	asm.emitPUSH_Reg(T1);                   // push high half (step 15)	asm.emitPUSH_Reg(T0);                   // push low half	asm.emitMOV_Reg_RegDisp (JTOC, PR, VM_Entrypoints.jtocOffset); // restore JTOC	break;      }      case 0x7c: /* iushr */ {	// unit test by IArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iushr");	if (VM.VerifyAssertions) VM.assert (ECX != T0);	asm.emitPOP_Reg (ECX);	asm.emitSHR_RegInd_Reg(SP, ECX);  // shift T0 right ECX times;  ECX low order 5 bits	break;      }      case 0x7d: /* lushr */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lushr");	if (VM.VerifyAssertions) VM.assert (ECX != T0); // ECX is constrained to be the shift count	if (VM.VerifyAssertions) VM.assert (ECX != T1);	if (VM.VerifyAssertions) VM.assert (ECX != JTOC);	// 1: pop shift amount into JTOC (JTOC must be restored at the end)	// 2: pop low half into T0	// 3: ECX <- JTOC, copy the shift count	// 4: JTOC <- JTOC & 32 --> if 0 then shift amount is less than 32	// 5: branch to step 11 if results is zero	// the result is not zero --> the shift amount is greater than 32	// 6: ECX <- ECX XOR JTOC   --> ECX is orginal shift amount minus 32	// 7: pop high half into T0 replace the low half with the high 	//        half.  This accounts for the 32 bit shift	// 8: shift T0 right logical by ECX bits	// 9: T1 <- 0                        T1 is the high half	// 10: branch to step 14	// 11: pop high half into T1	// 12: shift right double from T1 into T0 by ECX bits.  T1 is unaltered	// 13: shift right logical T1, the high half, also by ECX bits	// 14: push high half from T1	// 15: push the low half from T0	// 16: restore JTOC	asm.emitPOP_Reg(JTOC);                // original shift amount 6 bits	asm.emitPOP_Reg(T0);                  // pop low half 	asm.emitMOV_Reg_Reg(ECX, JTOC);	asm.emitAND_Reg_Imm(JTOC, 32);	VM_ForwardReference fr1 = asm.forwardJcc(asm.EQ);	asm.emitXOR_Reg_Reg (ECX, JTOC);	asm.emitPOP_Reg (T0);                   // replace low with high	asm.emitSHR_Reg_Reg (T0, ECX);      // and shift it (count - 32)	asm.emitXOR_Reg_Reg (T1, T1);               // high <- 0	VM_ForwardReference fr2 = asm.forwardJMP();	fr1.resolve(asm);	asm.emitPOP_Reg (T1);                   // high half (step 11)	asm.emitSHRD_Reg_Reg_Reg(T0, T1, ECX);          // shift low half	asm.emitSHR_Reg_Reg (T1, ECX);                   // shift high half	fr2.resolve(asm);	asm.emitPUSH_Reg(T1);                   // push high half (step 14)	asm.emitPUSH_Reg(T0);                   // push low half	asm.emitMOV_Reg_RegDisp (JTOC, PR, VM_Entrypoints.jtocOffset); // restore JTOC	break;      }      case 0x7e: /* iand */ {	// unit test by IArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iand");	asm.emitPOP_Reg(T0);	asm.emitAND_RegInd_Reg(SP, T0);	break;      }      case 0x7f: /* land */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "land");	asm.emitPOP_Reg(T0);        // low	asm.emitPOP_Reg(S0);        // high	asm.emitAND_RegInd_Reg(SP, T0);	asm.emitAND_RegDisp_Reg(SP, 4, S0);	break;      }      case 0x80: /* ior */ {	// unit test by IArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ior");	asm.emitPOP_Reg(T0);	asm.emitOR_RegInd_Reg (SP, T0);	break;      }      case 0x81: /* lor */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lor");	asm.emitPOP_Reg(T0);        // low	asm.emitPOP_Reg(S0);        // high	asm.emitOR_RegInd_Reg(SP, T0);	asm.emitOR_RegDisp_Reg(SP, 4, S0);	break;      }      case 0x82: /* ixor */ {	// unit test by IArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ixor");	asm.emitPOP_Reg(T0);	asm.emitXOR_RegInd_Reg(SP, T0);	break;      }      case 0x83: /* lxor */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lxor");	asm.emitPOP_Reg(T0);        // low	asm.emitPOP_Reg(S0);        // high	asm.emitXOR_RegInd_Reg(SP, T0);	asm.emitXOR_RegDisp_Reg(SP, 4, S0);	break;      }      case 0x84: /* iinc */ {	int index = fetch1ByteUnsigned();	int val = fetch1ByteSigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iinc " + VM_Lister.decimal(index) + " " + VM_Lister.decimal(val));	int offset = localOffset(index);	asm.emitADD_RegDisp_Imm(FP, offset, val);	break;      }      case 0x85: /* i2l */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2l");	asm.emitPOP_Reg (EAX);	asm.emitCDQ ();	asm.emitPUSH_Reg(EDX);	asm.emitPUSH_Reg(EAX);	break;      }      case 0x86: /* i2f */ {	// unit test by FArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2f");	asm.emitFILD_Reg_RegInd(FP0, SP);	asm.emitFSTP_RegInd_Reg(SP, FP0);	break;      }      case 0x87: /* i2d */ {	// unit test by DArith	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2d");	asm.emitFILD_Reg_RegInd(FP0, SP);	asm.emitPUSH_Reg(T0);             // grow the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);	break;      }      case 0x88: /* l2i */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "l2i");	asm.emitPOP_Reg (T0); // low half of the long	asm.emitPOP_Reg (S0); // high half of the long	asm.emitPUSH_Reg(T0);	break;      }      case 0x89: /* l2f */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "l2f");	asm.emitFILD_Reg_RegInd_Quad(FP0, SP);	asm.emitADD_Reg_Imm(SP, WORDSIZE);                // shrink the stack	asm.emitFSTP_RegInd_Reg(SP, FP0);	break;      }      case 0x8a: /* l2d */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "l2d");	asm.emitFILD_Reg_RegInd_Quad(FP0, SP);	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);	break;      }      case 0x8b: /* f2i */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "f2i");	// convert to double	asm.emitFLD_Reg_RegInd(FP0, SP);	asm.emitSUB_Reg_Imm(SP, WORDSIZE);                // grow the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);	// and convert to int	int offset = VM_Entrypoints.doubleToIntOffset;	genParameterRegisterLoad(); // pass 1 parameter	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);	break;      }      case 0x8c: /* f2l */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "f2l");	// convert to double	asm.emitFLD_Reg_RegInd(FP0, SP);	asm.emitSUB_Reg_Imm(SP, WORDSIZE);                // grow the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);	// and convert to long	int offset = VM_Entrypoints.doubleToLongOffset;	genParameterRegisterLoad(); // pass 1 parameter	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);        // high half	asm.emitPUSH_Reg(T1);        // low half	break;      }      case 0x8d: /* f2d */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "f2d");	asm.emitFLD_Reg_RegInd(FP0, SP);	asm.emitSUB_Reg_Imm(SP, WORDSIZE);                // grow the stack	asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);	break;      }      case 0x8e: /* d2i */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "d2i");	int offset = VM_Entrypoints.doubleToIntOffset;	genParameterRegisterLoad(); // pass 1 parameter	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);	break;      }      case 0x8f: /* d2l */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "d2l");	int offset = VM_Entrypoints.doubleToLongOffset;	genParameterRegisterLoad(); // pass 1 parameter	asm.emitCALL_RegDisp(JTOC, offset);	asm.emitPUSH_Reg(T0);        // high half	asm.emitPUSH_Reg(T1);        // low half	break;      }      case 0x90: /* d2f */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "d2f");	asm.emitFLD_Reg_RegInd_Quad(FP0, SP);	asm.emitADD_Reg_Imm(SP, WORDSIZE);                // shrink the stack	asm.emitFSTP_RegInd_Reg(SP, FP0);	break;      }      case 0x91: /* i2b */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2b");	//          asm.emitMOVSXb(T0, SP, 0); // load byte off top of the stack sign extended	//          asm.emitMOV   (SP, 0, T0); // store result back on the top of the stack	asm.emitPOP_Reg   (T0);	asm.emitMOVSX_Reg_Reg_Byte(T0, T0);	asm.emitPUSH_Reg  (T0);	break;      }      case 0x92: /* i2c */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2c");	//          asm.emitMOVZXh(T0, SP, 0); // load char off top of the stack sign extended	//          asm.emitMOV   (SP, 0, T0); // store result back on the top of the stack	asm.emitPOP_Reg   (T0);	asm.emitMOVZX_Reg_Reg_Word(T0, T0);	asm.emitPUSH_Reg  (T0);	break;      }      case 0x93: /* i2s */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "i2s");	//          asm.emitMOVSXh(T0, SP, 0); // load short off top of the stack sign extended	//          asm.emitMOV   (SP, 0, T0); // store result back on the top of the stack	asm.emitPOP_Reg   (T0);	asm.emitMOVSX_Reg_Reg_Word(T0, T0);	asm.emitPUSH_Reg  (T0);	break;      }      case 0x94: /* lcmp */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lcmp");  // a ? b	asm.emitPOP_Reg(T0);        // the low half of value2	asm.emitPOP_Reg(S0);        // the high half of value2	asm.emitPOP_Reg(T1);        // the low half of value1	asm.emitSUB_Reg_Reg(T1, T0);        // subtract the low half of value2 from                                // low half of value1, result into T1	asm.emitPOP_Reg(T0);        // the high half of value 1	//  pop does not alter the carry register	asm.emitSBB_Reg_Reg(T0, S0);        // subtract the high half of value2 plus                                // borrow from the high half of value 1,                                // result in T0	asm.emitMOV_Reg_Imm(S0, -1);        // load -1 into S0	VM_ForwardReference fr1 = asm.forwardJcc(asm.LT); // result negative --> branch to end	asm.emitMOV_Reg_Imm(S0, 0);        // load 0 into S0	asm.emitOR_Reg_Reg(T0, T1);        // result 0 	VM_ForwardReference fr2 = asm.forwardJcc(asm.EQ); // result 0 --> branch to end	asm.emitMOV_Reg_Imm(S0, 1);        // load 1 into S0	fr1.resolve(asm);	fr2.resolve(asm);	asm.emitPUSH_Reg(S0);        // push result on stack	break;      }      case 0x95: /* fcmpl !!- */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fcmpl");	VM_ForwardReference fr1,fr2,fr3;	asm.emitFLD_Reg_RegDisp(FP0, SP, WORDSIZE);          // copy value1 into FPU	asm.emitFLD_Reg_RegInd(FP0, SP);                        // copy value2 into FPU	asm.emitADD_Reg_Imm(SP, 2*WORDSIZE);                // popping the stack	if (VM.VerifyAssertions) VM.assert(S0 != EAX);                        // eax is used by FNSTSW	asm.emitXOR_Reg_Reg(S0, S0);                        // S0 <- 0	asm.emitFUCOMPP();                        // compare and pop FPU *2	asm.emitFNSTSW();                     // move FPU flags into (E)AX	asm.emitSAHF();                       // store AH into flags	fr1 = asm.forwardJcc(asm.EQ);        // branch if ZF set (eq. or unord.)	// ZF not set ->  neither equal nor unordered	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr2 = asm.forwardJcc(asm.LLT);        // branch if CF set (val2 < val1)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr1.resolve(asm);                        // ZF set (equal or unordered)	fr3 = asm.forwardJcc(asm.LGE);        // branch if CF not set (not unordered)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr3.resolve(asm);	fr2.resolve(asm);	asm.emitPUSH_Reg(S0);                        // push result on stack	break;      }      case 0x96: /* fcmpg !!- */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "fcmpg");	VM_ForwardReference fr1,fr2,fr3;	asm.emitFLD_Reg_RegDisp(FP0, SP, WORDSIZE);          // copy value1 into FPU	asm.emitFLD_Reg_RegInd(FP0, SP);                        // copy value2 into FPU	asm.emitADD_Reg_Imm(SP, 2*WORDSIZE);                // popping the stack	if (VM.VerifyAssertions) VM.assert(S0 != EAX);                        // eax is used by FNSTSW	asm.emitXOR_Reg_Reg(S0, S0);                        // S0 <- 0	asm.emitFUCOMPP();                        // compare and pop FPU *2	asm.emitFNSTSW();                     // move FPU flags into (E)AX	asm.emitSAHF();                       // store AH into flags	fr1 = asm.forwardJcc(asm.EQ);        // branch if ZF set (eq. or unord.)	// ZF not set ->  neither equal nor unordered	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr2 = asm.forwardJcc(asm.LLT);        // branch if CF set (val2 < val1)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr1.resolve(asm);                        // ZF set (equal or unordered)	fr3 = asm.forwardJcc(asm.LGE);        // branch if CF not set (not unordered)	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr3.resolve(asm);	fr2.resolve(asm);	asm.emitPUSH_Reg(S0);                        // push result on stack	break;      }      case 0x97: /* dcmpl !!- */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dcmpl");	VM_ForwardReference fr1,fr2,fr3;	asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, WORDSIZE*2);        // copy value1 into FPU	asm.emitFLD_Reg_RegInd_Quad(FP0, SP);                        // copy value2 into FPU	asm.emitADD_Reg_Imm(SP, 4*WORDSIZE);                // popping the stack	if (VM.VerifyAssertions) VM.assert(S0 != EAX);                        // eax is used by FNSTSW	asm.emitXOR_Reg_Reg(S0, S0);                        // S0 <- 0	asm.emitFUCOMPP();                        // compare and pop FPU *2	asm.emitFNSTSW();                     // move FPU flags into (E)AX	asm.emitSAHF();                       // store AH into flags	fr1 = asm.forwardJcc(asm.EQ);        // branch if ZF set (eq. or unord.)	// ZF not set ->  neither equal nor unordered	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr2 = asm.forwardJcc(asm.LLT);        // branch if CF set (val2 < val1)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr1.resolve(asm);                        // ZF set (equal or unordered)	fr3 = asm.forwardJcc(asm.LGE);        // branch if CF not set (not unordered)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr3.resolve(asm);	fr2.resolve(asm);	asm.emitPUSH_Reg(S0);                        // push result on stack	break;      }      case 0x98: /* dcmpg !!- */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dcmpg");	VM_ForwardReference fr1,fr2,fr3;	asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, WORDSIZE*2);        // copy value1 into FPU	asm.emitFLD_Reg_RegInd_Quad(FP0, SP);                        // copy value2 into FPU	asm.emitADD_Reg_Imm(SP, 4*WORDSIZE);                // popping the stack	if (VM.VerifyAssertions) VM.assert(S0 != EAX);                        // eax is used by FNSTSW	asm.emitXOR_Reg_Reg(S0, S0);                        // S0 <- 0	asm.emitFUCOMPP();                        // compare and pop FPU *2	asm.emitFNSTSW();                     // move FPU flags into (E)AX	asm.emitSAHF();                       // store AH into flags	fr1 = asm.forwardJcc(asm.EQ);        // branch if ZF set (eq. or unord.)	// ZF not set ->  neither equal nor unordered	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr2 = asm.forwardJcc(asm.LLT);        // branch if CF set (val2 < val1)	asm.emitMOV_Reg_Imm(S0, -1);                        // load -1 into S0	fr1.resolve(asm);                        // ZF set (equal or unordered)	fr3 = asm.forwardJcc(asm.LGE);        // branch if CF not set (not unordered)	asm.emitMOV_Reg_Imm(S0, 1);                        // load 1 into S0	fr3.resolve(asm);	fr2.resolve(asm);	asm.emitPUSH_Reg(S0);                        // push result on stack	break;      }      case 0x99: /* ifeq */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ifeq " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.EQ, mTarget, bTarget);	break;      }      case 0x9a: /* ifne */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ifne " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.NE, mTarget, bTarget);	break;      }      case 0x9b: /* iflt */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "iflt " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.LT, mTarget, bTarget);	break;      }      case 0x9c: /* ifge */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ifge " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.GE, mTarget, bTarget);	break;      }      case 0x9d: /* ifgt */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ifgt " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.GT, mTarget, bTarget);	break;      }      case 0x9e: /* ifle */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ifle " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Imm(T0, 0);	asm.emitJCC_Cond_ImmOrLabel(asm.LE, mTarget, bTarget);	break;      }      case 0x9f: /* if_icmpeq */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmpeq " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.EQ, mTarget, bTarget);	break;      }      case 0xa0: /* if_icmpne */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmpne " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.NE, mTarget, bTarget);	break;      }      case 0xa1: /* if_icmplt */ {	// maria  backward brach test is TESTED	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmplt " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.LT, mTarget, bTarget);	break;      }      case 0xa2: /* if_icmpge */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmpge " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.GE, mTarget, bTarget);	break;      }      case 0xa3: /* if_icmpgt */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmpgt " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.GT, mTarget, bTarget);	break;      }      case 0xa4: /* if_icmple */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_icmple " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.LE, mTarget, bTarget);	break;      }      case 0xa5: /* if_acmpeq */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_acmpeq " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.EQ, mTarget, bTarget);	break;      }      case 0xa6: /* if_acmpne */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "if_acmpne " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitPOP_Reg(S0);	asm.emitPOP_Reg(T0);	asm.emitCMP_Reg_Reg(T0, S0);	asm.emitJCC_Cond_ImmOrLabel(asm.NE, mTarget, bTarget);	break;      }      case 0xa7: /* goto */ {	// unit test by IBack	int offset = fetch2BytesSigned();	int bTarget = biStart + offset; // bi has been bumped by 3 already	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "goto " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] ");	if (offset < 0) genThreadSwitchTest(VM_Thread.BACKEDGE);	asm.emitJMP_ImmOrLabel(mTarget, bTarget);	break;      }      case 0xa8: /* jsr */ {	int offset = fetch2BytesSigned();	int bTarget = biStart + offset;	int mTarget = bytecodeMap[bTarget];	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "jsr " + VM_Lister.decimal(offset) + " [" + VM_Lister.decimal(bTarget) + "] (" + VM_Lister.decimal(mTarget));	asm.emitCALL_ImmOrLabel(mTarget, bTarget);	break;      }      case 0xa9: /* ret */ {	int index = fetch1ByteUnsigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ret " + VM_Lister.decimal(index));	int offset = localOffset(index);	asm.emitJMP_RegDisp(FP, offset); 	break;      }      case 0xaa: /* tableswitch */ {	// unit test by Table	bi = (bi+3) & -4; // eat padding	int defaultval = fetch4BytesSigned();	int bTarget = biStart + defaultval;	int mTarget = bytecodeMap[bTarget];	int low = fetch4BytesSigned();	int high = fetch4BytesSigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "tableswitch [" + VM_Lister.decimal(low) + "--" + VM_Lister.decimal(high) + "] " + VM_Lister.decimal(defaultval));	int n = high-low+1;                        // n = number of normal cases (0..n-1)	asm.emitPOP_Reg (T0);                          // T0 is index of desired case	asm.emitSUB_Reg_Imm(T0, low);                     // relativize T0	asm.emitCMP_Reg_Imm(T0, n);                       // 0 <= relative index < n	asm.emitJCC_Cond_ImmOrLabel (asm.LGE, mTarget, bTarget);   // if not, goto default case	asm.emitCALL_Imm(asm.getMachineCodeIndex() + 5 + (n<<LG_WORDSIZE) ); 	// jump around table, pushing address of 0th delta	for (int i=0; i<n; i++) {                  // create table of deltas	  int offset = fetch4BytesSigned();	  bTarget = biStart + offset;	  mTarget = bytecodeMap[bTarget];	  // delta i: difference between address of case i and of delta 0	  asm.emitOFFSET_Imm_ImmOrLabel(i, mTarget, bTarget );	}	asm.emitPOP_Reg (S0);                          // S0 = address of 0th delta 	asm.emitADD_Reg_RegIdx (S0, S0, T0, asm.WORD, 0);     // S0 += [S0 + T0<<2]	asm.emitPUSH_Reg(S0);                          // push computed case address	asm.emitRET ();                            // goto case	break;      }      case 0xab: /* lookupswitch */ {	// unit test by Lookup	bi = (bi+3) & -4; // eat padding	int defaultval = fetch4BytesSigned();	int npairs = fetch4BytesSigned();	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lookupswitch [<" + VM_Lister.decimal(npairs) + ">]" + VM_Lister.decimal(defaultval));	asm.emitPOP_Reg(T0);	for (int i=0; i<npairs; i++) {	  int match   = fetch4BytesSigned();	  asm.emitCMP_Reg_Imm(T0, match);	  int offset  = fetch4BytesSigned();	  int bTarget = biStart + offset;	  int mTarget = bytecodeMap[bTarget];	  asm.emitJCC_Cond_ImmOrLabel(asm.EQ, mTarget, bTarget);	}	int bTarget = biStart + defaultval;	int mTarget = bytecodeMap[bTarget];	asm.emitJMP_ImmOrLabel(mTarget, bTarget);	// TODO replace linear search loop with binary search	break;      }      case 0xac: /* ireturn */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "ireturn"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	asm.emitPOP_Reg(T0);	genEpilogue(); 	break;      }      case 0xad: /* lreturn */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "lreturn"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	asm.emitPOP_Reg(T1); // low half	asm.emitPOP_Reg(T0); // high half	genEpilogue();	break;      }      case 0xae: /* freturn */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "freturn"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	asm.emitFLD_Reg_RegInd(FP0, SP);	asm.emitADD_Reg_Imm(SP, WORDSIZE); // pop the stack	genEpilogue();	break;      }      case 0xaf: /* dreturn */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "dreturn"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	asm.emitFLD_Reg_RegInd_Quad(FP0, SP);	asm.emitADD_Reg_Imm(SP, WORDSIZE<<1); // pop the stack	genEpilogue();	break;      }      case 0xb0: /* areturn */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "areturn"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	asm.emitPOP_Reg(T0);	genEpilogue(); 	break;      }      case 0xb1: /* return */ {	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "return"); 	if (VM.UseEpilogueYieldPoints) genThreadSwitchTest(VM_Thread.EPILOGUE);	if (method.isSynchronized()) genMonitorExit();	genEpilogue(); 	break;      }      case 0xb2: /* getstatic */ {	int constantPoolIndex = fetch2BytesUnsigned();	VM_Field fieldRef = klass.getFieldRef(constantPoolIndex);	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "getstatic " + VM_Lister.decimal(constantPoolIndex)  + " (" + fieldRef + ")");	boolean classPreresolved = false;	VM_Class fieldRefClass = fieldRef.getDeclaringClass();	if (fieldRef.needsDynamicLink(method) && VM.BuildForPrematureClassResolution) {	  try {	    fieldRefClass.load();	    fieldRefClass.resolve();	    classPreresolved = true;	  } catch (Exception e) { // report the exception at runtime	    VM.sysWrite("WARNING: during compilation of " + method + " premature resolution of " + fieldRefClass + " provoked the following exception: " + e); // TODO!! remove this  warning message	  }	}	if (VM.BuildForPrematureClassResolution &&	    !fieldRefClass.isInitialized() &&	    !(fieldRefClass == klass) &&	    !(fieldRefClass.isInBootImage() && VM.writingBootImage)	    ) { // TODO!! rearrange the following code to backpatch after the first call	  asm.emitMOV_Reg_Imm (T0, fieldRefClass.getDictionaryId());	  asm.emitPUSH_Reg    (T0);	  asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.initializeClassIfNecessaryOffset);	  classPreresolved = true;	}	if (fieldRef.needsDynamicLink(method) && !classPreresolved) {	  if (VM.VerifyAssertions && VM.BuildForStrongVolatileSemantics) // Either VM.BuildForPrematureClassResolution was not set or the class was not found (these cases are not yet handled)	    VM.assert(VM.NOT_REACHED); // TODO!! handle this case by emitting code that assumes the field is volatile	  int offset = fieldRef.getDictionaryId()<<LG_WORDSIZE;  // offset of field in dictionary and in fieldOffsets	  int retryLabel = asm.getMachineCodeIndex();            // branch here after dynamic class loading	  asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.fieldOffsetsOffset);            // T0 is fieldOffsets table	  asm.emitMOV_Reg_RegDisp (T0, T0, offset);                          // T0 is offset in JTOC of static field, or 0 if field's class isn't loaded	  asm.emitCMP_Reg_Imm (T0, 0);                                   // T0 ?= 0, is field's class loaded?	  VM_ForwardReference fr = asm.forwardJcc(asm.NE);       // if so, skip 3 instructions	  int classId = fieldRef.getDeclaringClass().getDictionaryId();	  asm.emitPUSH_Imm(classId);                                 // pass an indirect pointer to field's class	  genParameterRegisterLoad(1);                           // pass 1 parameter word	  asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.loadClassOnDemandOffset);           // load field's class	  asm.emitJMP_Imm (retryLabel);                           // reload T0	  fr.resolve(asm);                                       // comefrom	  if (fieldRef.getSize() == 4) { // field is one word	    asm.emitPUSH_RegIdx (JTOC, T0, asm.BYTE, 0);        // get static field	  } else { // field is two words (double or long)	    if (VM.VerifyAssertions) VM.assert(fieldRef.getSize() == 8);	    // TODO!! use 8-byte move if possible	    asm.emitPUSH_RegIdx (JTOC, T0, asm.BYTE, WORDSIZE); // get high part	    asm.emitPUSH_RegIdx (JTOC, T0, asm.BYTE, 0);        // get low part	  }	} else {          fieldRef = fieldRef.resolve();	  int fieldOffset = fieldRef.getOffset();	  if (fieldRef.getSize() == 4) { // field is one word	    asm.emitPUSH_RegDisp(JTOC, fieldOffset);	  } else { // field is two words (double or long)	    if (VM.VerifyAssertions) VM.assert(fieldRef.getSize() == 8);            if (fieldRef.isVolatile() && VM.BuildForStrongVolatileSemantics) {	      asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.doublewordVolatileMutexOffset);	      asm.emitPUSH_Reg        (T0);	      asm.emitMOV_Reg_RegDisp (S0, T0, OBJECT_TIB_OFFSET);	      asm.emitCALL_RegDisp    (S0, VM_Entrypoints.processorLockOffset);	    }	    // TODO!! use 8-byte move if possible	    asm.emitPUSH_RegDisp(JTOC, fieldOffset+WORDSIZE); // get high part	    asm.emitPUSH_RegDisp(JTOC, fieldOffset);          // get low part            if (fieldRef.isVolatile() && VM.BuildForStrongVolatileSemantics) {	      asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.doublewordVolatileMutexOffset);	      asm.emitPUSH_Reg        (T0);	      asm.emitMOV_Reg_RegDisp (S0, T0, OBJECT_TIB_OFFSET);	      asm.emitCALL_RegDisp    (S0, VM_Entrypoints.processorUnlockOffset);	    }	  }	}	break;      }      case 0xb3: /* putstatic */ {	int constantPoolIndex = fetch2BytesUnsigned();	int fieldId = klass.getFieldRefId(constantPoolIndex);	VM_Field fieldRef = VM_FieldDictionary.getValue(fieldId);	if (VM_Assembler.TRACE) asm.noteBytecode(biStart, "putstatic " + VM_Lister.decimal(constantPoolIndex) + " (" + fieldRef + ")");	boolean classPreresolved = false;	VM_Class fieldRefClass = fieldRef.getDeclaringClass();	if (fieldRef.needsDynamicLink(method) && VM.BuildForPrematureClassResolution) {	  try {	    fieldRefClass.load();	    fieldRefClass.resolve();	    classPreresolved = true;	  } catch (Exception e) { // report the exception at runtime	    VM.sysWrite("WARNING: during compilation of " + method + " premature resolution of " + fieldRefClass + " provoked the following exception: " + e); // TODO!! remove this  warning message	  }	}	if (VM.BuildForPrematureClassResolution &&	    !fieldRefClass.isInitialized() &&	    !(fieldRefClass == klass) &&	    !(fieldRefClass.isInBootImage() && VM.writingBootImage)	    ) { // TODO!! rearrange the following code to backpatch after the first call	  asm.emitMOV_Reg_Imm (T0, fieldRefClass.getDictionaryId());	  asm.emitPUSH_Reg    (T0);	  asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.initializeClassIfNecessaryOffset);	  classPreresolved = true;	}	if (fieldRef.needsDynamicLink(method) && !classPreresolved) {	  if (VM.VerifyAssertions && VM.BuildForStrongVolatileSemantics) // Either VM.BuildForPrematureClassResolution was not set or the class was not found (these cases are not yet handled)	    VM.assert(VM.NOT_REACHED); // TODO!! handle this case by emitting code that assumes the field is volatile	  int offset = fieldRef.getDictionaryId()<<LG_WORDSIZE;  // offset of field in dictionary and in fieldOffsets	  int retryLabel = asm.getMachineCodeIndex();            // branch here, after dynamic class loading	  asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.fieldOffsetsOffset);            // T0 is fieldOffsets table	  asm.emitMOV_Reg_RegDisp (T0, T0, offset);                          // T0 is offset in JTOC of static field, or 0 if field's class isn't loaded	  asm.emitCMP_Reg_Imm (T0, 0);                                   // T0 ?= 0, is field's class loaded?	  VM_ForwardReference fr = asm.forwardJcc(asm.NE);       // if so, skip 3 instructions	  int classId = fieldRef.getDeclaringClass().getDictionaryId();	  asm.emitPUSH_Imm(classId);                                 // pass an indirect pointer to field's class	  genParameterRegisterLoad(1);                           // pass 1 parameter word	  asm.emitCALL_RegDisp(JTOC, VM_Entrypoints.loadClassOnDemandOffset);           // load field's class	  asm.emitJMP_Imm (retryLabel);                           // reload T0	  fr.resolve(asm);                                       // comefrom	  if (fieldRef.getSize() == 4) { // field is one word	    asm.emitPOP_RegIdx(JTOC, T0, asm.BYTE, 0);	  } else { // field is two words (double or long)	    if (VM.VerifyAssertions) VM.assert(fieldRef.getSize() == 8);	    // TODO!! use 8-byte move if possible	    asm.emitPOP_RegIdx(JTOC, T0, asm.BYTE, 0);        // store low part	    asm.emitPOP_RegIdx(JTOC, T0, asm.BYTE, WORDSIZE); // store high part	  }	} else {          fieldRef = fieldRef.resolve();	  int fieldOffset = fieldRef.getOffset();	  if (fieldRef.getSize() == 4) { // field is one word	    asm.emitPOP_RegDisp(JTOC, fieldOffset);	  } else { // field is two words (double or long)	    if (VM.VerifyAssertions) VM.assert(fieldRef.getSize() == 8);	    if (fieldRef.isVolatile() && VM.BuildForStrongVolatileSemantics) {	      asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.doublewordVolatileMutexOffset);	      asm.emitPUSH_Reg        (T0);	      asm.emitMOV_Reg_RegDisp (S0, T0, OBJECT_TIB_OFFSET);	      asm.emitCALL_RegDisp    (S0, VM_Entrypoints.processorLockOffset);	    }	    // TODO!! use 8-byte move if possible	    asm.emitPOP_RegDisp(JTOC, fieldOffset);          // store low part	    asm.emitPOP_RegDisp(JTOC, fieldOffset+WORDSIZE); // store high part            if (fieldRef.isVolatile() && VM.BuildForStrongVolatileSemantics) {	      asm.emitMOV_Reg_RegDisp (T0, JTOC, VM_Entrypoints.doublewordVolatileMutexOffset);	      asm.emitPUSH_Reg        (T0);	      asm.emitMOV_Reg_RegDisp (S0, T0, OBJECT_TIB_OFFSET);	      asm.emitCALL_RegDisp    (S0, VM_Entrypoints.processorUnlockOffset);	    }	  }	}	break;      }