s = _callHelper(s, ir); return s;
return callHelper(s, ir);
  private static OPT_Instruction generateValueProducingTypeCheck(OPT_Instruction s, 								 OPT_IR ir, 								 OPT_Operand RHSobj, 								 VM_Type LHStype, 								 OPT_RegisterOperand RHStib, 								 OPT_RegisterOperand result) {    // Is LHStype a class?    if (LHStype.isClassType()) {      VM_Class LHSclass = LHStype.asClass();      if (LHSclass.isResolved()) {	// Cases 4, 5, and 6 of VM_DynamicTypeCheck: LHSclass is a 	// resolved class or interface	if (LHSclass.isInterface()) {	  // A resolved interface (case 4)	  int interfaceIndex = LHSclass.getDoesImplementIndex();	  int interfaceMask = LHSclass.getDoesImplementBitMask();	  OPT_RegisterOperand doesImpl = 	    InsertUnary(s, ir,  GET_DOES_IMPLEMENT_FROM_TIB, 			OPT_ClassLoaderProxy.IntArrayType, RHStib);	  OPT_RegisterOperand entry = 	    InsertLoadOffset(s, ir, INT_LOAD, VM_Type.IntType, 			     doesImpl, interfaceIndex << 2, 			     new OPT_LocationOperand(VM_Type.IntType), 			     TG());	  OPT_RegisterOperand bit = InsertBinary(s, ir, INT_AND, VM_Type.IntType,						 entry, I(interfaceMask));	  s.insertBefore(BooleanCmp.create(BOOLEAN_CMP, result, 					   bit,					   I(0),					   OPT_ConditionOperand.NOT_EQUAL(),					   new OPT_BranchProfileOperand()));	  if (VM_DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {	    OPT_RegisterOperand doesImplLength = 	      InsertGuardedUnary(s, ir, ARRAYLENGTH, VM_Type.IntType, doesImpl.copy(), TG());	    OPT_RegisterOperand boundscheck = ir.regpool.makeTempInt();	    s.insertBefore(BooleanCmp.create(BOOLEAN_CMP, boundscheck, 					     doesImplLength,					     I(interfaceIndex),					     OPT_ConditionOperand.GREATER(),					     new OPT_BranchProfileOperand()));	    s.insertBefore(Binary.create(INT_AND, result.copyD2D(), 					 result.copyD2U(), boundscheck));	  }	  OPT_Instruction continueAt = s.prevInstructionInCodeOrder();	  s.remove();	  return continueAt;	} else {	  // A resolved class (cases 5 and 6 in VM_DynamicTypeCheck)	  if (LHSclass.isFinal()) {	    // For a final class, we can do a PTR compare of 	    // rhsTIB and the TIB of the class	    OPT_RegisterOperand classTIB = getTIB(s, ir, LHSclass);	    BooleanCmp.mutate(s, BOOLEAN_CMP, result, RHStib, classTIB, 			      OPT_ConditionOperand.EQUAL(),			      new OPT_BranchProfileOperand());	    return s.prevInstructionInCodeOrder();	  } else {	    // Do the full blown case 5 or 6 typecheck.	    int LHSDepth = LHSclass.getTypeDepth();	    int LHSId = LHSclass.getDictionaryId();	    OPT_RegisterOperand superclassIds = 	      InsertUnary(s, ir, GET_SUPERCLASS_IDS_FROM_TIB, 			  OPT_ClassLoaderProxy.ShortArrayType, RHStib);	    OPT_RegisterOperand refCandidate = 	      InsertLoadOffset(s, ir, USHORT_LOAD, VM_Type.ShortType, 			       superclassIds, LHSDepth << 1, 			       new OPT_LocationOperand(VM_Type.ShortType), 			       TG());	    s.insertBefore(BooleanCmp.create(BOOLEAN_CMP, result, 					     refCandidate, 					     I(LHSId), 					     OPT_ConditionOperand.EQUAL(),					     new OPT_BranchProfileOperand()));	    if (VM_DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {	      OPT_RegisterOperand superclassIdsLength = 		InsertGuardedUnary(s, ir, ARRAYLENGTH, VM_Type.IntType, 				   superclassIds.copyD2U(), TG());	      OPT_RegisterOperand boundscheck = ir.regpool.makeTempInt();	      s.insertBefore(BooleanCmp.create(BOOLEAN_CMP, boundscheck, 					       superclassIdsLength, 					       I(LHSDepth), 					       OPT_ConditionOperand.GREATER(),					       new OPT_BranchProfileOperand()));	      s.insertBefore(Binary.create(INT_AND, result.copyD2D(), 					   result.copyD2U(), boundscheck));	    }	    OPT_Instruction continueAt = s.prevInstructionInCodeOrder();	    s.remove();	    return continueAt;	  }	}      } else {	// A non-resolved class or interface. Case 3 of VM_DynamicTypeCheck	// Mutate s into a call to VM_DynamicTypeCheck.instanceOfUnresolved	OPT_RegisterOperand LHSRuntimeClass = getVMType(s, ir, LHSclass);	Call.mutate2(s, CALL, result, null, 		     OPT_MethodOperand.STATIC(VM_Entrypoints.instanceOfUnresolvedMethod), 		     LHSRuntimeClass, RHStib);	s = _callHelper(s, ir);	return s;      }    }    if (LHStype.isArrayType()) {      // Case 2 of VM_DynamicTypeCheck: LHS is an array.      VM_Array LHSArray = LHStype.asArray();      VM_Type innermostElementType = LHSArray.getInnermostElementType();      if (innermostElementType.isPrimitiveType() || 	  (innermostElementType.asClass().isResolved() && 	   innermostElementType.asClass().isFinal())) {	// [^k of primitive or [^k of final class. Just like final classes, 	// a PTR compare of rhsTIB and the TIB of the class gives the answer.	OPT_RegisterOperand classTIB = getTIB(s, ir, LHSArray);	BooleanCmp.mutate(s, BOOLEAN_CMP, result, RHStib, classTIB, 			  OPT_ConditionOperand.EQUAL(),new OPT_BranchProfileOperand());	return s;      }      // We're going to have to branch anyways, so reduce to a branching case       // and do the real work there.      return convertToBranchingTypeCheck(s, ir, RHSobj, LHStype, RHStib, result);    }    OPT_OptimizingCompilerException.UNREACHABLE();    return null;  }