OPT_MethodOperand mo = new OPT_MethodOperand(VM_Entrypoints.saveThreadStateInstructionsField, OPT_MethodOperand.STATIC, VM_Entrypoints.saveThreadStateInstructionsField.getOffset()); bc2ir.appendInstruction(Call.create1(CALL, null, null, mo, p1));
VM_Field target = VM_Entrypoints.saveThreadStateInstructionsField; OPT_MethodOperand mo = new OPT_MethodOperand(target); bc2ir.appendInstruction(Call.create1(CALL, null, new OPT_IntConstantOperand(target.getOffset()), mo, p1));
  static boolean generateMagic(OPT_BC2IR bc2ir, 			    OPT_GenerationContext gc, 			    VM_Method meth) throws OPT_MagicNotImplementedException {    if (gc.method.hasNoInlinePragma()) gc.allocFrame = true;        // HACK: Don't schedule any bbs containing unsafe magics.    // TODO: move this to individual magics that are unsafe.    // -- igor 08/13/1999    bc2ir.markBBUnsafeForScheduling();    VM_Atom methodName = meth.getName();    // VM.sysWriteln("OPT_GenerateMagic.generateMagic: method = ", methodName.toString());    if (methodName == VM_MagicNames.getProcessorRegister) {      OPT_RegisterOperand rop = gc.temps.makePROp();      bc2ir.markGuardlessNonNull(rop);      bc2ir.push(rop);    } else if (methodName == VM_MagicNames.setProcessorRegister) {      OPT_Operand val = bc2ir.popRef();      if (val instanceof OPT_RegisterOperand) {	bc2ir.appendInstruction(Move.create(REF_MOVE, 					    gc.temps.makePROp(), 					    val));      } else {	String msg = " Unexpected operand VM_Magic.setProcessorRegister";	throw OPT_MagicNotImplementedException.UNEXPECTED(msg);      }    } else if (methodName == VM_MagicNames.getIntAtOffset) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTempInt();      bc2ir.appendInstruction(Load.create(INT_LOAD, val, object, offset, 					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.setIntAtOffset) {      OPT_Operand val = bc2ir.popInt();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      bc2ir.appendInstruction(Store.create(INT_STORE, val, object, offset, 					   null));    } else if (methodName == VM_MagicNames.getLongAtOffset) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTempLong();      bc2ir.appendInstruction(Load.create(LONG_LOAD, val, object, offset, 					  null));      bc2ir.pushDual(val.copyD2U());    } else if (methodName == VM_MagicNames.setLongAtOffset) {      OPT_Operand val = bc2ir.popLong();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      bc2ir.appendInstruction(Store.create(LONG_STORE, val, object, offset, 					   null));    } else if (methodName == VM_MagicNames.setDoubleAtOffset) {      OPT_Operand val = bc2ir.popDouble();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      bc2ir.appendInstruction(Store.create(DOUBLE_STORE, val, object, offset, 					   null));    } else if (methodName == VM_MagicNames.getObjectAtOffset) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTemp(VM_Type.JavaLangObjectType);      bc2ir.appendInstruction(Load.create(INT_LOAD, val, object, offset, 					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.getObjectArrayAtOffset) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTemp(OPT_ClassLoaderProxy.JavaLangObjectArrayType);      bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, 					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.setObjectAtOffset) {      OPT_Operand val = bc2ir.popRef();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      bc2ir.appendInstruction(Store.create(INT_STORE, val, object, offset, 					   null));    } else if (methodName == VM_MagicNames.getByteAtOffset) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTemp(VM_Type.ByteType);      bc2ir.appendInstruction(Load.create(BYTE_LOAD, val, object, offset, 					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.setByteAtOffset) {      OPT_Operand val = bc2ir.popInt();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand object = bc2ir.popRef();      bc2ir.appendInstruction(Store.create(BYTE_STORE, val, object, offset, 					   null));    } else if (methodName == VM_MagicNames.getMemoryWord) {      OPT_Operand memAddr = bc2ir.popAddress();      OPT_RegisterOperand val = gc.temps.makeTempInt();      bc2ir.appendInstruction(Load.create(INT_LOAD, val, 					  memAddr, 					  new OPT_IntConstantOperand(0), 					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.getMemoryAddress) {      OPT_Operand memAddr = bc2ir.popAddress();      OPT_RegisterOperand val = gc.temps.makeTemp(VM_Type.AddressType);      bc2ir.appendInstruction(Load.create(INT_LOAD, val, 					  memAddr, 					  new OPT_IntConstantOperand(0),					  null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.setMemoryWord) {      OPT_Operand val = bc2ir.popInt();      OPT_Operand memAddr = bc2ir.popAddress();      bc2ir.appendInstruction(Store.create(INT_STORE, val, 					   memAddr, 					   new OPT_IntConstantOperand(0), 					   null));    } else if (methodName == VM_MagicNames.setMemoryAddress) {      OPT_Operand val = bc2ir.popRef();      OPT_Operand memAddr = bc2ir.popAddress();      bc2ir.appendInstruction(Store.create(INT_STORE, val, 					   memAddr, 					   new OPT_IntConstantOperand(0), 					   null));    } else if (methodName == VM_MagicNames.threadAsCollectorThread) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_CollectorThread;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsType) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.VM_Type_type);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsThread) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_Thread;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsProcessor) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.getVMProcessorType());      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsAddress) {      OPT_RegisterOperand reg = gc.temps.makeTemp(VM_Type.AddressType);      bc2ir.appendInstruction(Move.create(INT_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsObject) {      OPT_RegisterOperand reg = gc.temps.makeTemp(VM_Type.JavaLangObjectType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsObjectArray) {      OPT_RegisterOperand reg = gc.temps.makeTemp(OPT_ClassLoaderProxy.JavaLangObjectArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsType) {      OPT_RegisterOperand reg = gc.temps.makeTemp(OPT_ClassLoaderProxy.VM_Type_type);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());      //-#if RVM_WITH_JIKESRVM_MEMORY_MANAGERS    } else if (methodName == VM_MagicNames.addressAsBlockControl) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_BlockControl;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsSizeControl) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_SizeControl;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());      //-#endif    } else if (methodName == VM_MagicNames.addressAsThread) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_Thread;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsRegisters) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.findOrCreateType("Lcom/ibm/JikesRVM/VM_Registers;", VM_SystemClassLoader.getVMClassLoader()));      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsByteArray) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.ByteArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsIntArray) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.IntArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsByteArray) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.ByteArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsShortArray) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.ShortArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.objectAsIntArray) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.IntArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.addressAsStack) {      OPT_RegisterOperand reg = 	gc.temps.makeTemp(OPT_ClassLoaderProxy.IntArrayType);      bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));      bc2ir.push(reg.copyD2U());    } else if (methodName == VM_MagicNames.floatAsIntBits) {      OPT_Operand val = bc2ir.popFloat();      OPT_RegisterOperand op0 = gc.temps.makeTempInt();      bc2ir.appendInstruction(Unary.create(FLOAT_AS_INT_BITS, op0, val));      bc2ir.push(op0.copyD2U());    } else if (methodName == VM_MagicNames.intBitsAsFloat) {      OPT_Operand val = bc2ir.popInt();      OPT_RegisterOperand op0 = gc.temps.makeTempFloat();      bc2ir.appendInstruction(Unary.create(INT_BITS_AS_FLOAT, op0, val));      bc2ir.push(op0.copyD2U());    } else if (methodName == VM_MagicNames.doubleAsLongBits) {      OPT_Operand val = bc2ir.popDouble();      OPT_RegisterOperand op0 = gc.temps.makeTempLong();      bc2ir.appendInstruction(Unary.create(DOUBLE_AS_LONG_BITS, op0, val));      bc2ir.pushDual(op0.copyD2U());    } else if (methodName == VM_MagicNames.longBitsAsDouble) {      OPT_Operand val = bc2ir.popLong();      OPT_RegisterOperand op0 = gc.temps.makeTempDouble();      bc2ir.appendInstruction(Unary.create(LONG_BITS_AS_DOUBLE, op0, val));      bc2ir.pushDual(op0.copyD2U());    } else if (methodName == VM_MagicNames.getObjectType) {      OPT_Operand val = bc2ir.popRef();      OPT_Operand guard = bc2ir.getGuard(val);      if (guard == null) {	// it's magic, so assume that it's OK....        guard = new OPT_TrueGuardOperand();       }      OPT_RegisterOperand tibPtr =         gc.temps.makeTemp(OPT_ClassLoaderProxy.JavaLangObjectArrayType);      bc2ir.appendInstruction(GuardedUnary.create(GET_OBJ_TIB, tibPtr,                                                   val, guard));      OPT_RegisterOperand op0;      VM_Type argType = val.getType();      if (argType.isArrayType()) {        op0 = gc.temps.makeTemp(OPT_ClassLoaderProxy.VM_Array_type);      } else {	if (argType == VM_Type.JavaLangObjectType ||	    argType == VM_Type.JavaLangCloneableType || 	    argType == VM_Type.JavaIoSerializableType) {	  // could be an array or a class, so make op0 be a VM_Type.	  op0 = gc.temps.makeTemp(OPT_ClassLoaderProxy.VM_Type_type);	} else {	  op0 = gc.temps.makeTemp(OPT_ClassLoaderProxy.VM_Class_type);	}      }      bc2ir.markGuardlessNonNull(op0);      bc2ir.appendInstruction(Unary.create(GET_TYPE_FROM_TIB, op0,                                            tibPtr.copyD2U()));      bc2ir.push(op0.copyD2U());    } else if (methodName == VM_MagicNames.getArrayLength) {      OPT_Operand val = bc2ir.popRef();      OPT_RegisterOperand op0 = gc.temps.makeTempInt();      bc2ir.appendInstruction(GuardedUnary.create(ARRAYLENGTH, op0, val,                                                   new OPT_TrueGuardOperand()));      bc2ir.push(op0.copyD2U());    } else if (methodName == VM_MagicNames.invokeClassInitializer) {      OPT_Instruction s = Call.create0(CALL, null, bc2ir.popRef(), null);      bc2ir.appendInstruction(s);    } else if (methodName == VM_MagicNames.invokeMain) {      OPT_Operand code = bc2ir.popRef();      OPT_Operand args = bc2ir.popRef();      bc2ir.appendInstruction(Call.create1(CALL, null, code, null, args));    } else if ((methodName == VM_MagicNames.invokeMethodReturningObject)               || (methodName == VM_MagicNames.invokeMethodReturningVoid)                || (methodName == VM_MagicNames.invokeMethodReturningLong)                || (methodName == VM_MagicNames.invokeMethodReturningDouble)                || (methodName == VM_MagicNames.invokeMethodReturningFloat)                || (methodName == VM_MagicNames.invokeMethodReturningInt)) {      OPT_Operand spills = bc2ir.popRef();      OPT_Operand fprs = bc2ir.popRef();      OPT_Operand gprs = bc2ir.popRef();      OPT_Operand Code = bc2ir.popRef();      OPT_RegisterOperand res = null;      if (methodName == VM_MagicNames.invokeMethodReturningObject) {        res = gc.temps.makeTemp(VM_Type.JavaLangObjectType);        bc2ir.push(res.copyD2U());      } else if (methodName == VM_MagicNames.invokeMethodReturningLong) {        res = gc.temps.makeTemp(VM_Type.LongType);        bc2ir.push(res.copyD2U(), VM_Type.LongType);      } else if (methodName == VM_MagicNames.invokeMethodReturningDouble) {        res = gc.temps.makeTempDouble();        bc2ir.push(res.copyD2U(), VM_Type.DoubleType);      } else if (methodName == VM_MagicNames.invokeMethodReturningFloat) {        res = gc.temps.makeTempFloat();        bc2ir.push(res.copyD2U(), VM_Type.FloatType);      } else if (methodName == VM_MagicNames.invokeMethodReturningInt) {        res = gc.temps.makeTempInt();        bc2ir.push(res.copyD2U());      }      OPT_MethodOperand met = 	new OPT_MethodOperand(VM_Entrypoints.reflectiveMethodInvokerInstructionsField,			      OPT_MethodOperand.STATIC, 			      VM_Entrypoints.reflectiveMethodInvokerInstructionsField.getOffset());      OPT_Instruction s = Call.create4(CALL, res, null, met, Code, gprs, 				       fprs, spills);      bc2ir.appendInstruction(s);    } else if (methodName == VM_MagicNames.saveThreadState) {      OPT_Operand p1 = bc2ir.popRef();      OPT_MethodOperand mo = 	new OPT_MethodOperand(VM_Entrypoints.saveThreadStateInstructionsField,			      OPT_MethodOperand.STATIC, 			      VM_Entrypoints.saveThreadStateInstructionsField.getOffset());      bc2ir.appendInstruction(Call.create1(CALL, null, null, mo, p1));    } else if (methodName == VM_MagicNames.threadSwitch) {      OPT_Operand p2 = bc2ir.popRef();      OPT_Operand p1 = bc2ir.popRef();      OPT_MethodOperand mo = 	new OPT_MethodOperand(VM_Entrypoints.threadSwitchInstructionsField,			      OPT_MethodOperand.STATIC, 			      VM_Entrypoints.threadSwitchInstructionsField.getOffset());      bc2ir.appendInstruction(Call.create2(CALL, null, null, mo, p1, p2));    } else if (methodName == VM_MagicNames.restoreHardwareExceptionState) {      OPT_MethodOperand mo = 	new OPT_MethodOperand(VM_Entrypoints.restoreHardwareExceptionStateInstructionsField,			      OPT_MethodOperand.STATIC, 			      VM_Entrypoints.restoreHardwareExceptionStateInstructionsField.getOffset());      bc2ir.appendInstruction(Call.create1			      (CALL, null, null, mo, bc2ir.popRef()));    } else if (methodName == VM_MagicNames.prepare) {      OPT_Operand offset = bc2ir.popInt();      OPT_Operand base = bc2ir.popRef();      OPT_RegisterOperand val = gc.temps.makeTempInt();      bc2ir.appendInstruction(Prepare.create(PREPARE, val, base, offset, null));      bc2ir.push(val.copyD2U());    } else if (methodName == VM_MagicNames.attempt) {      OPT_Operand newVal = bc2ir.popInt();      OPT_Operand oldVal = bc2ir.popInt();      OPT_Operand offset = bc2ir.popInt();      OPT_Operand base = bc2ir.popRef();      OPT_RegisterOperand test = gc.temps.makeTempInt();      bc2ir.appendInstruction(Attempt.create(ATTEMPT, test, base, offset, oldVal, 					     newVal, null));      bc2ir.push(test.copyD2U());    } else if (generatePolymorphicMagic(bc2ir, gc, meth, methodName)) {      return true;    } else if (methodName == VM_MagicNames.getTimeBase) {      OPT_RegisterOperand op0 = gc.temps.makeTempLong();      bc2ir.appendInstruction(Nullary.create(GET_TIME_BASE, op0));      bc2ir.pushDual(op0.copyD2U());    } else {      // Wasn't machine-independent, so try the machine-dependent magics next.      boolean generated = OPT_GenerateMachineSpecificMagic.generateMagic(bc2ir, gc, meth);      // if (!generated) VM.sysWriteln("Magic method not implemented: " + meth);      return generated;    }    return true;  } // generateMagic